バックグラウンドジョブ
ルール
- 低速な処理はバックグラウンドジョブにオフロードする:メール、画像処理、Webhook、レポート、AI APIコール
- 自己管理のRedisキューにはBullMQ — サーバーレス/マネージドには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リクエストハンドラ内で低速なタスクを処理する — 迅速に応答し、バックグラウンドで処理する
- 冪等でないジョブ — 重複実行により二重請求、二重メールが発生する
- 無制限の同時実行 — データベース接続とメモリを枯渇させる
- ジョブキューに大きなペイロードを保存する — 代わりに参照を渡す