指南

如何在網頁 App 中執行背景工作:佇列、排程器與 Cron

要在網頁 App 中執行背景工作,首先要把工作分成兩種。觸發式工作(發送歡迎郵件、處理上傳的檔案)可以存入工作佇列,通常是資料庫中的一張表,並由具備重試機制的工作程式處理。排程式工作(每晚的報表、每 15 分鐘一次的提醒)則需要某種能按時程觸發的機制:主機的 cron 功能,或是呼叫你 App 中受保護端點的外部排程器。務必讓工作能安全地重複執行、記錄失敗情況,而且絕不要依賴那個可能休眠或重新啟動的伺服器內部計時器。

本指南說明各種選項、各自適合的情境,以及如何透過 AI App 建置工具進行設定,包括在會縮減至零的主機上。

什麼算是背景工作

任何緩慢、不可靠,或不是使用者立即回應所必需的工作:

  • 寄送電子郵件、通知與收據
  • 調整圖片大小、轉碼影片、產生 PDF
  • 呼叫緩慢的第三方 API,包括執行長時間任務的 AI 模型
  • 從其他系統匯入或同步資料
  • 每晚的清理、報表與提醒

把這些工作放在請求流程中,會讓頁面變慢且脆弱:如果郵件服務商故障,使用者的註冊就會失敗。把它們移到背景執行,使用者就能立即得到回應,而且工作可以重試。

各種選項

選項運作方式優點缺點
同一程序中的即發即忘先回應,然後在伺服器中繼續執行工作不需設定伺服器停止時會遺失;沒有重試
程序內計時器(setInterval、setTimeout)在執行中的伺服器內建立計時器非常簡單伺服器休眠時不會執行;多個副本時會重複
資料庫式佇列工作以資料列儲存;工作程式認領並執行使用你既有的資料庫;持久耐用;容易檢查你需要自行實作重試與鎖定;需要某個東西來執行工作程式
專用佇列(基於 Redis 或託管服務)佇列服務加上工作程式重試與排程功能成熟又多一個需要運行與付費的服務
託管的工作或工作流程服務第三方會呼叫你的端點,並提供重試與排程排程與重試都由服務處理依賴廠商;多一個帳號與金鑰
外部排程器呼叫端點其他地方的計時器依排程發送 HTTP 請求可在任何主機上運作,包括縮減至零的主機有最短間隔與延遲;需要保護端點
主機內建的 cron平台依排程執行指令有提供時簡單易用並非每個主機都提供

沒有唯一正確的答案。小型 App 通常只需要一個資料庫佇列加上外部排程器。

為什麼縮減至零的主機改變了情況

許多現代主機在沒有人使用你的 App 時會讓它休眠,並在下一次請求時喚醒。這樣能省錢,但休眠中的伺服器不會執行任何程式碼:計時器不會觸發,工作程式也不會輪詢。在這些主機上,排程工作必須由一個進來的請求來啟動,而最簡單的請求來源就是外部排程器。每次呼叫都會喚醒 App(通常也會喚醒資料庫),因此每分鐘呼叫一次的成本,會高於每 15 分鐘呼叫一次。請選擇能滿足需求的最慢排程。

模式一:資料庫工作佇列

適用於觸發式工作:

  1. 建立一張 jobs 表:類型、酬載(JSON)、狀態(pending、running、done、failed)、嘗試次數、run_after、last_error、時間戳記。
  2. 當某件事發生時,在造成該變更的同一個交易中插入一筆工作資料列,讓兩者同時成功或同時失敗。
  3. 工作程式挑選到期的工作,將其標記為 running,執行後標記為 done。
  4. 失敗時,增加 attempts,把 run_after 設定到更晚的時間(例如 1 分鐘、5 分鐘,然後 30 分鐘),並儲存錯誤訊息。達到最大次數後,將其標記為 failed 並通知相關人員。

如果可能有多個工作程式同時運行,工作必須被安全地認領。在 Postgres 上,SELECT ... FOR UPDATE SKIP LOCKED 能讓每個工作程式認領不同的資料列,而不會互相衝突。

由什麼來執行工作程式?在一直運行的伺服器上,可以是獨立程序中的迴圈。在縮減至零的主機上,模式二中的排程端點可以在每次呼叫時處理一批到期的工作。

模式二:由外部排程器呼叫你的 App

適用於排程式工作:

  1. 新增一個端點,例如 POST /api/cron/send-reminders。
  2. 保護它:要求在標頭中帶有一組機密權杖,該權杖作為機密儲存在雙方,並拒絕其他任何請求。
  3. 讓它具備冪等性:同一分鐘內執行兩次,不可以寄出兩次提醒。記錄已經寄出的內容。
  4. 讓每次呼叫都簡短:處理一批(例如 100 筆),剩下的由下一次呼叫接手。
  5. 將排程器指向這個端點。

排程器的選擇:

  • GitHub Actions 排程工作流程。 在 GitHub 的使用限制內免費。根據 GitHub 截至 2026 年 9 月的文件,最短間隔為每 5 分鐘一次;在尖峰時段(特別是每小時的開頭)執行可能會延遲;排程預設使用 UTC;而公開儲存庫中的排程工作流程,若超過 60 天沒有儲存庫活動,會被停用。
  • 託管的 cron 服務。 有許多服務的唯一工作就是依排程呼叫一個網址。在依賴它之前,請檢查其可靠性、最短間隔與告警功能。
  • 你的雲端服務商排程器。 如果你已經在使用大型雲端服務商,它會提供可以呼叫 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。

設定排程觸發:

新增受不記名權杖保護的 POST /api/cron/tick,權杖來自機密 CRON_SECRET;沒有該權杖的請求一律拒絕。每次呼叫都執行 processJobs(100),並寄出未來 24 小時內到期、且尚未寄出的預約提醒,同時記錄已寄出的提醒,確保不會重複寄送。以 JSON 摘要回傳執行結果。接著撰寫一個 GitHub Actions 工作流程,每 15 分鐘呼叫這個端點一次,並從儲存庫機密中讀取網址與權杖。

常見錯誤

  • 依賴 setInterval。 當伺服器休眠或重新啟動時,它會悄悄停止;而當兩個副本同時運行時,又會重複執行。
  • 未受保護的 cron 端點。 任何找到它的人都能觸發你的工作,或是讓你的電子郵件帳單暴增。
  • 工作不具冪等性。 重試與重複的排程器呼叫一定會發生。設計時就要考慮到這點。
  • 沒有失敗的可見性。 一項工作悄悄失敗一整週,比大聲失敗更糟。請記錄錯誤,並對重複的失敗發出警示。
  • 在單一請求中執行很長的工作。 請求會逾時。請分批處理。
  • 排程太頻繁。 在縮減至零的主機上,每次呼叫都會喚醒並計費。請讓間隔配合實際需求。
  • 時區問題。「早上 9 點」對你的排程器(通常是 UTC)與對你的使用者意義不同。請以 UTC 儲存時間,並依使用者換算。
  • 把機密寫在工作流程檔案中。 請把權杖保存在排程器的機密儲存區中。請參閱如何安全地保管 API 金鑰。

檢查清單

  • 緩慢的工作已移出使用者請求
  • 工作被持久儲存,而不只存在記憶體中
  • 重試採用遞增的延遲時間,並設有最大次數
  • 每項工作都能安全地重複執行
  • 排程端點受到機密權杖保護
  • 每次執行都處理有限的一批
  • 失敗的工作可見,並設有警示
  • 排程間隔的選擇已考慮託管成本
  • 時間以 UTC 儲存

Mythex 中的背景工作

Mythex 的文件並未說明排程或 cron 工作,而且已發布的 App 與其資料庫在閒置時會休眠,並在下一次請求時喚醒(請參閱主機限制)。因此,不要依賴 App 內部的計時器。可行的做法是上述的方式:請 Agent 為你建立一張 jobs 表與一個受權杖保護的端點,然後將外部排程器指向你已發布的網址。把權杖存為專案機密,並記住每次喚醒都會為 App 與資料庫醒著的時間消耗點數,因此請選擇合理的間隔。如果你的 App 需要 API 後端來處理這件事,REST API 後端教學是很好的起點,而如何建置 REST API則說明了如何設計端點。如果你的產品核心是需要持續運行的工作程式或機器人,那麼專為持久性程序設計的主機可能更適合你。

常見問題

什麼是背景工作?

背景工作是指 App 在使用者正在等待的請求之外所執行的工作,例如寄送電子郵件、調整圖片大小、產生報表或同步資料。使用者能快速得到回應,工作則另外執行,失敗時也可以重試。

如果主機沒有 cron,我要如何執行排程任務?

新增一個受保護的端點來執行工作,然後讓外部排程器依照時程呼叫它。可選的方式包括排程的 GitHub Actions 工作流程、託管的 cron 服務,或你雲端服務商的排程功能。請用一組機密權杖來保護這個端點。

排程任務可以使用 setInterval 或 setTimeout 嗎?

只適合用於小型、不重要的工作,而且伺服器必須持續運行。如果伺服器重新啟動、縮減至零,或同時運行多個副本,計時器就會遺失,或重複執行。請把排程工作存放在資料庫中,或使用排程器。

Mythex 支援 cron 工作嗎?

Mythex 的文件並未說明排程或 cron 工作,而且已發布的 App 在閒置時會休眠。最可靠的做法是讓外部排程器呼叫你 App 中受保護的端點,這會喚醒 App 並執行工作。

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 简体中文 繁體中文(香港)