← 所有文章2026.10.11 · 軟體設計

什麼時候該用 Message Queue?先確認你真的需要非同步

Queue 能解耦、多路分發並吸收尖峰,但也帶來重複訊息、最終一致性與追蹤成本。小規模系統不一定需要它。

結論先行

Message queue 的價值不是讓系統看起來比較分散式,而是讓 producer 不必等待 consumer,也不必知道有哪些 consumer。

如果呼叫者必須立刻知道結果,例如登入、查價、庫存確認或建立付款,同步 API 通常更直接。當工作可以稍後完成、需要多個 consumer、流量會突然爆發,或上下游必須各自運行,queue 才開始有明確價值。

適合 Message Queue 的情境

一個事件有多個 consumer

訂單完成後,帳務、通知、分析與會員系統都要處理,但建立訂單的服務不應逐一等待它們。

flowchart LR
  P[Order Service] --> Q[Message Queue]
  Q --> A[Accounting]
  Q --> N[Notification]
  Q --> D[Analytics]

多個系統需要同步狀態

核心系統發出狀態變更,由搜尋索引、資料倉儲、CRM 或第三方整合各自更新。這裡的「同步」是資料最後要一致,不代表必須在同一個 request 內完成。

需要吸收瞬間尖峰

先讓工作排隊,再按照下游能承受的速度消化,避免 API、資料庫或外部供應商被瞬間流量打滿。Queue 在這裡同時是 buffer 和 backpressure boundary。

耗時工作不應阻塞使用者

匯出報表、處理圖片、寄送通知或執行批次計算,可以先回覆使用者「已接受」,再由 consumer 處理。

需要重試、隔離與 replay

暫時失敗的訊息可以延後重試,反覆失敗後進入 dead-letter queue;如果 consumer 修正完成,保存的事件也能重新處理。

上下游需要獨立生命週期

Producer 和 consumer 由不同團隊維護,部署頻率、容量和故障時間都不同。Queue 可以降低兩者必須同時在線的耦合。

什麼時候同步呼叫更好?

情境 優先選擇
呼叫者必須立即取得成功或失敗 同步 API
單一 producer、單一 consumer、低流量 先用同步 API 或簡單 job
同一個程式與資料庫內的短流程 函式呼叫或 transaction
多個 consumer,各自獨立處理 Message queue
需要緩衝尖峰與保護下游 Message queue
可以接受 eventual consistency Message queue
流程必須立即一致 同步流程,或重新設計交易邊界

Queue 帶來的成本

採用 queue 前,團隊至少要願意處理:

  • 重複送達與 idempotency。
  • 訊息順序和 eventual consistency。
  • Schema 版本與新舊 consumer 相容。
  • Consumer lag、retry、dead-letter queue 與告警。
  • 跨服務 tracing,以及「訊息現在卡在哪裡」的查找能力。
Queue 的收益
= 解耦 + 緩衝 + 多路分發 + 獨立擴展

Queue 的成本
= 一致性 + 重複處理 + 可觀測性 + 維運複雜度

如果成本大於目前的解耦價值,先保持同步會更清楚。等到第二個 consumer 出現、尖峰開始壓垮下游,或上下游確實需要不同生命週期,再引入 queue 也不遲。

最後的判斷

我現在不會因為「未來可能有很多服務」就預先加入 message queue,而是尋找可觀察的觸發條件:consumer 數量增加、同步等待開始影響使用者、尖峰超過下游容量,或跨系統失敗已經需要獨立重試。

有非同步需求,不代表一定需要 message queue;有兩個系統,也不代表必須用事件串接。先採用最容易理解與維護的流程,等 queue 能解決一個已經存在的問題時再導入,通常才是成本與架構都合理的時機。