長時間執行任務 (Manage Long-Running Tasks)

核心問題

抓資料只要 100ms,但產生 PDF 報告 / 影片轉碼 / 批量寄信要 30 秒到數分鐘。同步處理下:

模式核心:把「接受請求」和「處理請求」解耦

Web server 變成輕量請求路由器:驗證 → 推進 queue → 立刻回傳 job ID(毫秒)。獨立的 worker pool 做真正繁重的工作。


解法架構

Client ──► Web Server ──push──► Queue ──pull──► Worker Pool
              │ (毫秒回 job ID)                    │
              ▼                                    ▼
          DB (job: pending) ◄──update status── (processing → completed/failed)

完整流程:

  1. Web server 驗證請求,DB 建立 pending job 記錄
  2. 推訊息進 queue(只放 job ID,不放完整資料
  3. 立刻回傳 job ID 給 client
  4. Worker 從 queue 拉訊息 → 從 DB 抓 job 詳情
  5. 更新狀態為 processing → 執行工作 → 存結果(檔案 S3、metadata DB)
  6. 更新為 completed / failed
每個元件可獨立失敗,系統仍運作

Queue 掛 → web server 照收,job 在 DB 堆積;worker 崩 → job 留 queue 等新 worker;DB 出問題 → worker 持續重試。


取捨

得到 失去
快速回應(ms 回 job ID,不 timeout) 系統複雜度(queue、worker、狀態追蹤)
獨立擴展(web 用便宜機,worker 用 GPU 機) 最終一致性(回傳時工作還沒完成)
故障隔離(一台 worker 崩不拖垮 API) Job 狀態追蹤基礎設施(增加 DB 負載)
更好的資源利用 監控 overhead(queue 深度、worker 健康、失敗率)

新故障模式:queue 滿了?poison message 一直讓 worker 崩?何時放棄重試?


兩個核心元件

Message Queue(需持久化 durable)

選項 特點 注意
Redis + Bull/BullMQ startup 首選,設定簡單,自動重試/延遲/優先權 memory-first,硬崩可能丟 job
AWS SQS 全託管、保證送達 1MB 訊息上限(所以只傳 ID);大規模成本高
RabbitMQ 複雜路由、企業久經考驗 自行架設、運維負擔
Kafka 超大流量、可重播、partition 內保序 event streaming 技術棧首選

Worker Pool

運行方式 適合 限制
一般 server 長時間 job、完全控制、易除錯 閒置也要付費
Serverless(Lambda) 流量高峰不穩定 15~60 分執行上限、cold start、本地儲存小
Container(K8s/ECS) 中間方案,自動擴展 比 serverless 複雜
面試別過度複雜化

沒特殊理由就選 Kafka(或你熟的 queue),worker 用一般 server process。重點是展示關注點分離,不是辯論 queue 技術優劣。


何時主動提出(識別信號)

關鍵技能:主動出擊

你應該是那個指出操作太慢的人,而不是等面試官問。展示你在他們提顧慮前,就在想 timeout、資源利用率、用戶體驗。


常見 Deep Dive(五大故障處理)


常見系統範例

系統 async 任務
YouTube 轉碼多解析度、產縮圖、提字幕、內容審核
Instagram 多尺寸、濾鏡、metadata、圖片識別加標籤、feed fan-out
Robotaxi 乘車配對(評估可用性、算路線、定價)、位置更新
Stripe 詐欺偵測、3D Secure、webhook、延遲清算
Dropbox 病毒掃描、搜尋索引、產生預覽、多裝置同步