目錄
RabbitMQ 的主角不是 queue 名稱,而是 producer 先把訊息送到 exchange,再由 binding 規則路由到一個或多個 queue。direct、topic、fanout 與 headers exchange 能把工作分派、廣播、pattern routing 和 dead-letter flow 留在 broker topology,而不是散落在每個 producer 裡。
如果需求是「這個工作一定要有人處理,失敗要重試,依類型送到不同 worker」,RabbitMQ 通常比 partitioned log 更貼近問題本身。
Exchange、binding、queue 各負責一件事
producer publish 到 exchange,exchange 根據 routing key 與 binding 決定目的 queue;consumer 從 queue 收 delivery。多個 consumer 讀同一 queue 時,工作會被分配;多個 queue 綁同一 exchange 時,每個 queue 都能收到副本。這兩種拓撲不能混為一談。
producer -> orders(topic exchange)
| orders.paid.*
+--> fulfillment queue -> workers
| orders.*.failed
+--> incident queue -> on-call worker
這套模型比 Kafka consumer group 更擅長細緻路由,也更自然地支援短生命週期工作、priority、TTL 與 dead-letter exchange。代價是訊息通常在 ack 後刪除;若需要多組 consumer 任意回到舊位置重播,應看 RabbitMQ Streams、Kafka 或 Redpanda。
Quorum queue 是高可用工作的預設
Quorum queue 以 Raft 複寫持久化 queue,是 RabbitMQ 對資料安全與 leader election 的現代預設。RabbitMQ 4.0 已移除 classic queue mirroring;新系統不要照舊教學建立 mirrored classic queue。
quorum queue 適合長期存在、重要且需要複寫的工作 queue。它不適合大量 transient/exclusive queue、最低延遲、超長 backlog 或大規模 fan-out;後兩者官方建議評估 stream。三個 member 是常見起點,增加 member 會增加共識成本,並不是越多越安全。
Confirm 與 ack 是兩個方向的責任移交
publisher confirm 表示 broker 已接手訊息;quorum queue 會在訊息被 quorum 接受後 confirm。consumer manual acknowledgement 表示應用已完成必要處理,broker 才能刪除 delivery。只設 durable queue、persistent message,卻沒有 confirm 與 manual ack,仍可能在 publish 或 consume 邊界丟資料。
channel.prefetch(20);
channel.consume("fulfillment", async (msg) => {
if (!msg) return;
try {
await processOrder(JSON.parse(msg.content.toString()));
channel.ack(msg);
} catch {
channel.nack(msg, false, false);
}
});
manual ack 帶來 at-least-once:worker 做完 side effect、還沒 ack 就 crash,訊息會重送。因此 processOrder 仍需 idempotency key;nack 是否 requeue 也要明確,否則 poison message 可能無限迴圈。quorum queue 有 delivery limit 與 poison-message handling,但 dead-letter policy 仍要由團隊設計。
RabbitMQ Streams 不是普通 queue 的加速模式
RabbitMQ Streams 是可持久化、可複寫、non-destructive consumption 的 append-only log,同一筆訊息可被重讀。Super streams 再以 partition 擴充吞吐。它讓既有 RabbitMQ cluster 能承接部分 event-streaming use case,但 message priority、per-message TTL 等 queue 語意不會完整保留。
需要 AMQP routing 和可靠背景工作時用 quorum queue。需要同一 broker 裡的重播與高吞吐時評估 streams。若整個平台都以長期事件日誌、CDC 與 stream processing 為中心,Kafka 生態通常更完整。
AI 工作負載的實際用法
RabbitMQ 適合排 LLM batch、文件解析、embedding、工具執行與 webhook retry。訊息放 task ID、tenant、輸入位置與 idempotency key,不要塞完整文件。設定 prefetch 來限制 worker 同時持有的未 ack 工作,並讓 retry 有上限、退避與 dead-letter queue。
agent task 可能跑很久。不要靠延長 ack timeout 假裝它已成為 durable execution;worker crash 後,RabbitMQ 只知道重新交付整筆訊息,不知道流程做完哪些 step。需要逐步恢復、等待人類數小時或跨多個外部呼叫時,Temporal、Restate 或 Trigger.dev 才是對應層。
參考資料
Loading...