🎯 什麼情境該想到我
當你「想在不影響主流程的前提下,複製一份經過通道的訊息送去監看或分析」的時候。
⚙️ 怎麼用(步驟 / 公式)
意圖:在通道上插入一個固定的收件者,把每則訊息複製一份送到次要通道,同時把原訊息照常轉往主通道。
做法 / 結構要點:
- 在通道中放一個竊聽器(一種 recipient list / 分岔器)。
- 收到訊息後,一份原封不動送往原目的地,另一份送到監看 / 分析通道。
- 監看端可記錄、稽核、分析,不干擾主流程。
★ 今天這個模式大多不需要自己做
| 需求 | ★ 現成方案 |
|---|---|
| 看到所有訊息 | ★ Kafka 天生就是——訊息讀了不會消失,開一個新的 consumer group 就是竊聽器 |
| 稽核/合規紀錄 | ★ Kafka 的 compacted/長 retention topic;或 CDC 到資料倉儲 |
| 分散式追蹤 | ★★ OpenTelemetry——它做的正是「複製一份觀測資料出去」 |
| RabbitMQ 上 | ★ fanout exchange 或 Firehose 追蹤插件 |
★★ 最重要的一點:在 Kafka 上「竊聽器」是免費的。
訊息保留在 log 裡,任何人開一個新的 consumer group 就能讀到全部——
這是 Kafka 相對傳統佇列最實用的差異之一(見 發布訂閱通道)。
★ 在 RabbitMQ 上就要刻意設計(fanout + 一個 audit queue)。
★★ Go 的實作:竊聽的失敗不能影響主流程
func (t *Tap) Handle(ctx context.Context, msg Message) error {
// ★★ 先做主流程 —— 竊聽是附加的,不是前置條件
if err := t.main.Handle(ctx, msg); err != nil { return err }
// ★ 竊聽:非阻塞、有界、失敗只計數
select {
case t.taps <- msg: // ★ 有界 channel
default:
metrics.TapDropped.Inc() // ★★ 滿了就丟,不要阻塞主流程
}
return nil
}★★ default 分支是關鍵:
沒有它 → 竊聽的下游變慢時,主流程會被阻塞——
★ 這就把「一個觀測功能」變成了「一個可用性風險」。
★ 代價是「竊聽資料不完整」,而那通常是可以接受的取捨(觀測 ≠ 稽核)。
⚠️ 但如果是合規/稽核用途,「丟掉」不可接受 → 那就不能用這種寫法,
必須是「同步寫入可靠的稽核通道,失敗就讓主流程失敗」。
→ ★ 判準:這份複本是「觀測」還是「證據」? 決定了它能不能被丟棄。
★★ 最危險的一點:竊聽通道會累積 PII
★ 竊聽通道是「所有訊息的完整複本」
→ ① ★★ 主流程可能有 [[內容過濾器]] 遮蔽了敏感欄位,★ 而竊聽的是原始訊息
② ★ 稽核通道的 retention 通常最長(合規要求幾年)
③ ★ 權限通常較寬(稽核人員、資安、資料團隊都要看)
→ ★★ 於是「你最不想留存的資料,留在保留期最長、權限最寬的地方」
★ 三個必做的事:
- 竊聽前先遮蔽(不是竊聽後才想起來)。
- 獨立且更嚴格的存取控制,並記錄誰查了什麼。
- 明確的保留期與刪除機制(GDPR 的刪除請求也涵蓋稽核紀錄)。
⚠️ 這一點對這個知識庫本身也適用:發布到公開網站的內容會被快取與存檔,
「之後刪掉」不等於「消失了」。
★ 竊聽的三個用途與各自的設計要求
| 用途 | 完整性要求 | 可以丟訊息嗎 |
|---|---|---|
| ★ 觀測/除錯 | 低 | ✅ 可以(取樣即可) |
| ★ 指標統計 | 中 | ✅ 可以(但要知道取樣率) |
| ★★ 稽核/合規 | ★ 必須完整 | ❌ 不可以 ⇒ 必須同步且可靠 |
★★ 把這三種混在同一條竊聽通道上是常見的錯誤:
你會為了「除錯方便」而保留稽核級的完整資料,或為了「效能」而讓稽核資料可以被丟棄。
★ 兄弟辨析
| 差別 | |
|---|---|
| 繞道 | ★ 訊息真的改走另一條路(介入);竊聽只是複製(旁觀) |
| 訊息存放區 | ★ 竊聽器是「怎麼取得複本」;訊息存放區是「複本存在哪、怎麼查」 |
| 訊息歷史 | 記錄在訊息裡面的路徑紀錄 |
| 智慧代理 | 竊聽 + 記錄請求-回覆的配對 |
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
-
複製會增加一點負擔;監看通道要能吸收流量。
-
只讀觀察,不應改動主流程訊息。
-
常與訊息歷史 / 訊息存放區搭配做分析。
-
★★ 在 Kafka 上竊聽器是免費的(開一個新 consumer group)。RabbitMQ 上要刻意設計 fanout。
-
★★ 竊聽的失敗與延遲不能影響主流程。有界 channel +
default分支丟棄,代價是複本不完整。 -
★★ 判準:這份複本是「觀測」還是「證據」? 證據不能被丟棄 ⇒ 必須同步且可靠,那是完全不同的設計。
-
★★ 竊聽通道會累積 PII,而且它保留期最長、權限最寬。要在竊聽前遮蔽,不是之後才想起來。
-
★ 不要把觀測、指標、稽核混在同一條竊聽通道上。三者的完整性要求完全不同。
-
★ 稽核紀錄也受 GDPR 刪除請求約束,要有刪除機制。
-
★ OpenTelemetry 做的就是這件事,不要自己造一個平行的觀測管線。
-
竊聽會讓訊息量翻倍(頻寬、儲存、broker 負載)。全量竊聽高流量通道前先算一下成本。
🔗 相關工具
- 訊息歷史 Message History(同家族,記錄訊息經過的路徑)
- 訊息存放區 Message Store(同家族,複製的訊息常存進這裡)
- 企業整合模式
- 繞道 —— 介入而非旁觀
- 訊息存放區 —— 複本存在哪、怎麼查
- 訊息歷史 —— 記在訊息裡的路徑
- 智慧代理 —— 竊聽 + 請求-回覆配對
- 內容過濾器 —— ★ 竊聽前先遮蔽 PII
- 工具-遙測與監控 —— OTel 的觀測管線