背景工作
規則
- 將耗時工作卸載到背景工作:電子郵件、圖片處理、Webhook、報表、AI 呼叫
- BullMQ 用於自託管 Redis 佇列 — Inngest 或 Trigger.dev 用於無伺服器/託管方案
- 每項工作必須是冪等的 — 重試時安全無副作用(使用冪等金鑰)
- 使用指數退避重試:3-5 次嘗試,延遲 1 秒、10 秒、60 秒、5 分鐘
- 死信佇列(DLQ):超過最大重試次數後,移至 DLQ 進行調查 — 絕不靜默丟棄
- 為每個佇列設定並發限制 — 防止工作者過載(例如
concurrency: 5)
- 工作負載應保持輕量:傳遞 ID 和參考值,而非完整物件
- 按優先級分離佇列:
critical(付款)、default(電子郵件)、low(分析)
- 監控佇列深度和處理時間 — 當佇列積壓時發出警報
模式
import { Queue, Worker } from "bullmq";
const queue = new Queue("emails", { connection: redis });
await queue.add("welcome", { userId }, {
attempts: 3,
backoff: { type: "exponential", delay: 1000 },
});
const worker = new Worker("emails", async (job) => {
await sendWelcomeEmail(job.data.userId);
}, { connection: redis, concurrency: 5 });
import { inngest } from "./client";
export const sendEmail = inngest.createFunction(
{ id: "send-welcome-email", retries: 3 },
{ event: "user/created" },
async ({ event }) => { await sendWelcomeEmail(event.data.userId); }
);
避免
- 在 API 請求處理常式中處理慢速任務 — 快速響應,背景處理
- 非冪等工作 — 重複執行會導致重複收費、重複寄送電子郵件
- 無限制的並發 — 會耗盡資料庫連線和記憶體
- 在佇列中儲存大型負載 — 改傳遞參考值