指南

如何在Web应用中运行后台任务:队列、调度器与Cron

要在Web应用中运行后台任务,首先要把工作分成两类。触发式任务(发送欢迎邮件、处理上传文件)可以保存到任务队列中,通常是数据库中的一张表,并由带有重试机制的工作进程处理。定时任务(每晚生成报告、每15分钟发送提醒)则需要按时间表触发:可以使用主机的cron功能,或由外部调度器调用你应用中受保护的端点。务必让任务可以安全地重复运行,记录失败情况,并且永远不要依赖一个可能休眠或重启的服务器内部的计时器。

本指南介绍了各种选项、每种选项的适用场景,以及如何借助AI应用构建器进行设置,包括在支持缩容至零的主机上的做法。

什么算作后台任务

任何缓慢、不可靠或对用户即时响应并非必需的工作:

  • 发送邮件、通知和收据
  • 调整图片大小、转码视频、生成PDF
  • 调用缓慢的第三方API,包括用于长时间任务的AI模型
  • 从其他系统导入或同步数据
  • 每晚的清理、报告和提醒

如果把这些工作放在请求过程中同步完成,页面会变慢且脆弱:如果邮件服务商宕机,用户的注册就会失败。将其移到后台,用户可以立即得到响应,而任务也可以重试。

可选方案

方案工作方式优点缺点
同一进程中的“即发即忘”先响应,然后在服务器中继续执行工作无需设置服务器停止时会丢失;没有重试
进程内计时器(setInterval、setTimeout)在运行中的服务器中设置计时器非常简单服务器休眠时不运行;多个副本时会重复执行
数据库支持的队列任务以行的形式保存;工作进程领取并执行它们使用你已有的数据库;持久可靠;便于检查需要自己实现重试和加锁;需要有东西来运行工作进程
专用队列(基于Redis或托管式)队列服务加上工作进程成熟的重试和调度功能另一项需要运行和付费的服务
托管的任务或工作流服务第三方服务带着重试和调度调用你的端点调度和重试由服务商处理依赖供应商;需要另一个账户和密钥
外部调度器调用端点其他地方的计时器按时发送HTTP请求适用于任何主机,包括缩容至零的主机存在最小间隔和延迟;需要保护端点
主机内置的cron平台按计划运行命令在支持的地方很简单并非每个主机都提供

没有唯一正确的答案。一个小型应用通常只需要一个数据库队列加上一个外部调度器。

缩容至零的主机如何改变了情况

许多现代主机在没有人使用应用时让它休眠,并在下一次请求时将其唤醒。这样可以节省费用,但休眠的服务器不运行任何代码:计时器不会触发,工作进程也不会轮询。在这些主机上,定时工作必须由一个传入的请求来启动,而最简单的请求来源就是外部调度器。每次调用都会唤醒应用(通常还包括其数据库),因此每分钟调用一次的成本高于每15分钟调用一次。应选择满足需求的最慢调度频率。

方案一:数据库任务队列

适用于触发式任务:

  1. 创建一张jobs表:类型、载荷(JSON)、状态(pending、running、done、failed)、尝试次数、run_after、last_error、时间戳。
  2. 当某件事发生时,在引起该变化的同一事务中插入一条任务记录,使两者同时成功或同时失败。
  3. 工作进程领取到期的任务,将其标记为running,执行工作,然后标记为done。
  4. 失败时,增加尝试次数,将run_after设置到更晚的时间(例如1、5、30分钟后),并保存错误信息。达到最大次数后,将其标记为failed并通知相关人员。

如果可能有多个工作进程同时运行,任务必须被安全地领取。在Postgres上,SELECT ... FOR UPDATE SKIP LOCKED可以让每个工作进程领取不同的行而不会发生冲突。

什么来运行工作进程?在始终运行的服务器上,可以是一个独立进程中的循环。在缩容至零的主机上,方案二中的定时端点可以在每次调用时处理一批到期的任务。

方案二:外部调度器调用你的应用

适用于定时任务:

  1. 添加一个端点,例如POST /api/cron/send-reminders。
  2. 保护它:要求在请求头中携带一个密钥令牌,该令牌在双方都作为密钥保存,并拒绝其他任何请求。
  3. 让它具备幂等性:在同一分钟内运行两次不能发送两条提醒。记录已经发送过的内容。
  4. 让每次调用都简短:处理一批(例如100条),由下一次调用处理剩余的内容。
  5. 将调度器指向该端点。

调度器的选择:

  • GitHub Actions定时工作流。 在GitHub的使用限制内免费。截至2026年9月,GitHub的文档说明,最短间隔为每5分钟一次;运行可能会因高峰时段(尤其是每个整点)而延迟;调度默认使用UTC时间;如果公共仓库在60天内没有任何仓库活动,其定时工作流将被禁用。
  • 托管的cron服务。 有许多服务的唯一用途就是按计划调用某个URL。在依赖它之前,请检查其可靠性、最小间隔和告警功能。
  • 云服务商的调度器。 如果你已经在使用大型云服务商,它会提供可以调用HTTPS端点的托管调度器。
  • 托管的任务或工作流服务。 这些服务结合了调度、队列和重试,并在每个步骤中调用你的端点。请在各供应商的网站上比较其价格和限制。

方案三:交给服务商处理

有时最好的后台任务是根本不需要自己做:

  • 付款。 Stripe会重试失败的订阅付款并发送Webhook;你只需对此做出响应,而无需轮询。参阅什么是Webhook。
  • 邮件。 当你把邮件交给服务商后,服务商会对投递进行排队和重试。
  • 批量AI工作。 OpenAI和Anthropic为非紧急请求提供批量API,你提交请求后再稍后收取结果。

提交给AI构建器的提示词

对于队列:

使用我们数据库中的jobs表(类型、JSON载荷、状态、尝试次数、run_after、last_error)添加一个后台任务队列。当用户注册时,在同一事务中插入一条send_welcome_email任务,而不是同步发送。添加一个processJobs(limit)函数,使用SELECT ... FOR UPDATE SKIP LOCKED领取到期的任务并执行它们,失败后在1、5和30分钟后重试,并在4次尝试后将其标记为failed。

对于定时触发:

添加一个由密钥CRON_SECRET中的bearer令牌保护的POST /api/cron/tick;拒绝任何不带该令牌的请求。每次调用运行processJobs(100),并发送未来24小时内到期且尚未发送的预订提醒,记录已发送的提醒,确保不会重复发送。以JSON摘要的形式返回运行结果。然后编写一个GitHub Actions工作流,每15分钟调用一次该端点,并从仓库密钥中读取URL和令牌。

常见误区

  • 依赖setInterval。 当服务器休眠或重启时,它会悄无声息地停止;当两个副本同时运行时,它又会重复执行。
  • 未受保护的cron端点。 任何发现它的人都可以触发你的任务,或者让你的邮件账单增加。
  • 任务不具备幂等性。 重试和重复的调度器调用一定会发生。设计时要考虑到这一点。
  • 没有故障可见性。 一个悄无声息地失败了一周的任务,比明显地失败更糟。记录错误,并在反复失败时发出告警。
  • 在单个请求中进行长时间运行。 请求会超时。应分批处理。
  • 调度过于频繁。 在缩容至零的主机上,每次调用都会唤醒并计费应用。应使调度间隔与实际需求相匹配。
  • 时区。 “早上9点”对调度器(通常是UTC)和你的用户而言含义不同。应以UTC存储时间,并为每个用户进行转换。
  • 工作流文件中的密钥。 应把令牌保存在调度器的密钥存储中。参阅如何安全地保管API密钥。

检查清单

  • 已将较慢的工作移出用户请求
  • 任务持久保存,而不只是存在内存中
  • 重试采用递增的延迟,并设有最大次数
  • 每个任务都可以安全地重复运行
  • 定时端点受密钥令牌保护
  • 每次运行处理的批量大小有上限
  • 失败的任务可见,并设有告警
  • 已结合托管成本选择了调度间隔
  • 时间以UTC存储

Mythex中的后台任务

Mythex的文档没有描述定时任务或cron任务,而且已发布的应用及其数据库在闲置时会休眠,并在下一次请求时唤醒(参阅托管限制)。因此,不要依赖应用内部的计时器。行之有效的做法是上面所述的方法:请智能体为你添加一张任务表和一个受令牌保护的端点,然后将外部调度器指向你已发布的URL。将令牌保存为项目密钥,并且要注意,每次唤醒都会按应用和数据库保持唤醒的时间消耗积分,因此请选择合理的间隔。如果你的应用需要为此使用API后端,REST API后端教程是一个起点,而如何构建REST API则涵盖了端点的设计。如果你的产品核心是常驻的工作进程或机器人,那么专为持续运行进程设计的主机可能更适合你。

常见问题

什么是后台任务?

后台任务是应用在用户等待的请求之外完成的工作,例如发送邮件、调整图片大小、生成报告或同步数据。用户能够快速得到响应,任务则单独运行,失败时还可以重试。

如果我的主机没有cron,如何运行定时任务?

添加一个受保护的端点来完成工作,然后让外部调度器按时间表调用它。可选方案包括定时运行的GitHub Actions工作流、托管的cron服务,或云服务商的调度器。使用密钥令牌保护该端点。

我可以用setInterval或setTimeout来运行定时任务吗?

只适用于在始终运行的服务器上执行的小型、不重要的任务。如果服务器重启、缩容至零或运行多个副本,计时器就会丢失,或者被执行多次。应把定时工作存储在数据库中,或使用调度器。

Mythex支持cron任务吗?

Mythex的文档没有描述定时任务或cron任务,而且已发布的应用在闲置时会休眠。最可靠的做法是让外部调度器调用你应用中受保护的端点,这样会唤醒应用并执行工作。

Mythex · Pricing · 用 AI 构建任何东西 · 网站和应用模板 · Mythex 对比 · AI 应用构建术语表 · 免费的 AI 应用构建工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 繁體中文(香港) 繁體中文(台灣)