結論先行
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 能解決一個已經存在的問題時再導入,通常才是成本與架構都合理的時機。