🎯 什麼情境該想到我
當你「要讓發送者把訊息送到接收者,但兩者不該彼此直接知道對方」的時候:中間需要一條講好的邏輯管道。
⚙️ 怎麼用(步驟 / 公式)
意圖:用訊息系統中的邏輯通道連接發送者與接收者;發送者把訊息寫入通道,接收者從通道讀取。
做法 / 結構要點:
- 通道是有名字、有位址的邏輯路徑,決定訊息往哪裡流。
- 發送者只需知道要寫入哪個通道,不需知道誰在接收(反之亦然)。
- 通道的種類(點對點 / 發布訂閱等)決定訊息被一個或多個接收者取用。
★ 「通道」在各家 broker 裡叫什麼
| 點對點通道 | 發布訂閱通道 | |
|---|---|---|
| Kafka | ★ topic + 同一個 consumer group | topic + 多個 consumer group |
| RabbitMQ | queue(多個 consumer 競爭) | fanout/topic exchange → 每個 consumer 一個 queue |
| SQS/SNS | SQS queue | SNS topic → 多個 SQS queue |
| NATS JetStream | stream + queue group | stream + 多個 durable consumer |
★★ Kafka 的關鍵差異:通道的「種類」不是建立時決定的,而是由消費者怎麼分組決定的。
同一個 topic,一個 consumer group 讀 = 點對點;三個 group 各自讀 = 發布訂閱。
這和 EIP 書裡「queue vs topic 是兩種東西」的模型不同——寫 2003 年的 JMS 時沒有這個選項。
★★ 通道命名與治理:這是唯一真正會痛的長期問題
# ★ 一套可行的命名規範(領域.實體.事件.版本)
orders.order.placed.v1
billing.invoice.issued.v1
inventory.stock.reserved.v1
# ★ 為什麼要帶版本:schema 不相容變更時,你需要能「同時跑兩條通道」
orders.order.placed.v1 ← 舊消費者
orders.order.placed.v2 ← 新消費者
要在規範裡定死的五件事:
- ★ 命名格式(誰擁有這個通道,一看就知道)
- ★ 這是命令還是事件通道(語義不可混用,見 命令訊息/事件訊息)
- ★ schema 放在哪(schema registry、
.protorepo) - ★ retention 多久(Kafka 的
retention.ms、SQS 的 retention、RabbitMQ 的 TTL) - 誰可以寫入(★ 寫入權就是所有權)
★ 一個通道應該只承載一種訊息型別——這就是 資料型別通道。
混著放,消費者每則都要先判斷型別,等於自己實作一個路由器。
★ 通道數量的實務上限(不是無限的)
Kafka:★ 分區總數是有成本的(每個分區 = 檔案句柄 + 記憶體 + controller metadata)
單叢集數千到數萬分區是常見上限;★ 「每個使用者一個 topic」一定會爆
RabbitMQ:★ 每個 queue 是一個 Erlang process。數萬 queue 可行,但長佇列會拖慢整體
SQS:★ 帳號級配額限制;動態建立大量 queue 要先確認配額
★ 反模式:用「每個實體一個通道」來做隔離。
要隔離就用分區鍵(同一個實體的訊息進同一個分區),不要用通道數量。
★ Go 的通道 ≠ EIP 的通道
ch := make(chan Order, 100) // ★ Go 的 channel:行程內、無持久化、行程死了就沒了兩者名字一樣但完全不同層次。Go channel 沒有持久化、沒有重送、沒有 DLQ。
⚠️ 常見錯誤:用 buffered channel 當「佇列」來削峰 → 行程重啟就丟光。
(Go channel 的正確用法見 工具-靠通訊共享記憶體。)
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
-
通道是設計時決定的固定路徑,不是動態內容路由;要依內容分流請用路由器。
-
通道數量過多會增加管理負擔,需要命名與治理規範。
-
★ Kafka 裡「點對點 vs 發布訂閱」是由消費者分組決定的,不是通道型別。這和 EIP 的 JMS 模型不同。
-
★★ 通道命名與治理是唯一會長期痛的問題。命名要看得出擁有者,並帶版本。
-
★ 一個通道只放一種訊息型別(資料型別通道)。混放等於強迫每個消費者自己路由。
-
★ 不要用「每個實體一個通道」做隔離。分區數/queue 數都有實際上限,要隔離就用分區鍵。
-
★ retention 是設計決定,不是預設值。Kafka 過期就真的沒了;SQS 最長 14 天。
-
★ Go 的
chan不是訊息通道:行程內、無持久化。用它削峰,重啟就丟光。 -
通道是設計時的固定路徑,依內容分流要用 訊息路由器。
🔗 相關工具
- 點對點通道 Point-to-Point Channel(訊息通道的一種:一則訊息只給一個接收者)
- 發布訂閱通道 Publish-Subscribe Channel(訊息通道的一種:一則訊息廣播給所有訂閱者)
- 訊息 Message(在通道上傳輸的資料封包)
- 企業整合模式
- 點對點通道、發布訂閱通道 —— 兩種基本型態
- 資料型別通道 —— 一個通道只放一種訊息
- 訊息路由器 —— 依內容動態分流
- 無效訊息通道、死信通道 —— 兩種特殊通道
- 工具-資料分區 —— 分區鍵決定順序與並行度
- 工具-靠通訊共享記憶體 —— Go channel 的正確用法