🎯 什麼情境該想到我
當你「只想讓符合條件的訊息通過,其餘直接丟棄」的時候。
⚙️ 怎麼用(步驟 / 公式)
意圖:從通道中剔除不感興趣的訊息。
做法要點:
- 過濾器檢查每一則訊息是否符合條件。
- 符合就原樣轉出;不符合就丟棄。
- 是「只有單一輸出、且輸出為零或一則」的特例路由。
- 常用於發布訂閱情境,讓各接收端只留下自己關心的訊息。
★★ 最重要的決定:過濾應該發生在哪一端
① ★ 生產端不發 → 最省(零網路、零處理),但生產者要知道「誰不要什麼」
② ★★ broker 過濾 → 最佳:省網路、零額外元件
RabbitMQ topic exchange/headers exchange、SNS filter policy、NATS 通配
③ 獨立的過濾器元件 → ★ 多一跳、多一個部署單元
④ ★ 消費端過濾 → 最簡單,但白收所有訊息(見 [[選擇性消費者]])
★★ 順序就是這個順序。 先問 ①②,再考慮 ③。
★ Kafka 特別注意:它沒有 broker 端過濾(除了分區),所以在 Kafka 上
「過濾」只有 ① 和 ④——要嘛分流成不同 topic,要嘛消費端全收再丟。
④ 的成本可以估算:
訊息 2 KB × 每秒 10,000 則 × 只有 5% 有用
→ ★ 白收 19 MB/s 的網路 + 反序列化 CPU
→ 值不值得加一個過濾器元件?★ 自己算,不要憑感覺
★★ 這個模式最大的風險:丟掉的訊息沒有痕跡
// ❌ 靜默丟棄 —— 過濾器與 bug 長得一模一樣
if !match(e) { return msg.Ack() }
// ✅ 至少要有指標;高價值訊息還要有紀錄
if !match(e) {
metrics.Filtered.WithLabelValues(e.Type, reason(e)).Inc() // ★ 帶原因的標籤
return msg.Ack()
}★★ 「為什麼那筆訂單沒進來」最難查的情況,就是它被某個過濾器丟掉了——
因為沒有錯誤、沒有日誌、沒有痕跡。
★ 過濾器和「有 bug 的路由器」在外部觀察上完全無法區分。★ 對策的三個層次:
① 一定要有帶原因標籤的計數器(最低要求)。
② 高價值訊息:丟棄前寫一筆紀錄(誰、為什麼、什麼時候)。
③ ★ 可疑時改成「導流」而非「丟棄」:送到一條filtered.orders通道
(這就是 繞道)——留著,但不進主流程。
★ 過濾條件的維護:這是長期的痛點
// ★ 條件要是純函式 + 有測試 —— 它是業務規則,不是設定
func shouldProcess(e Envelope) (bool, string) {
if e.Region != "TW" { return false, "region" } // ★ 回傳原因,用於指標
if e.Amount < minAmount { return false, "below_min" }
return true, ""
}⚠️ 兩個常見的腐敗:
- ★ 條件累積成沒人敢改的一團:
if a && !b && (c || d) && !e——
每一項都是某次事故留下的補丁,而沒有人記得為什麼。
→ ★ 每個條件旁邊註記「為什麼」與「什麼時候可以拿掉」(見 註釋 的第③類)。 - ★ 過濾條件散落在多個元件:生產者過一次、broker 過一次、消費者再過一次
→ 「這筆為什麼沒到」要查三個地方。盡量只在一處過濾。
★ 兄弟辨析
| 差別 | |
|---|---|
| 內容路由器 | ★ 不符條件的訊息去另一個通道;過濾器直接丟掉 |
| 選擇性消費者 | ★ 同一件事發生在消費端(消費者只挑自己要的) |
| 繞道 | ★ 把訊息導去別處而不是丟掉——★ 通常是過濾器更好的替代 |
| 內容過濾器 | ★★ 名字像但完全不同:它移除訊息裡的欄位,不是丟掉整則訊息 |
🧪 我實際套用的紀錄
- (待填)
⚠️ 注意 / 什麼時候不適用
-
與內容路由器不同:過濾器可能完全不輸出(把訊息丟掉)。
-
若過濾邏輯分散在多個接收端,可考慮改用內容路由器集中控管。
-
被丟棄的訊息通常不保留,需要留存時要另做處理。
-
★★ 過濾順序:生產端不發 > broker 過濾 > 獨立元件 > 消費端過濾。 先問前兩個。
-
★ Kafka 沒有 broker 端過濾。只能分流成不同 topic,或消費端全收再丟。
-
★★ 靜默丟棄的過濾器和有 bug 的路由器無法區分。 至少要有帶原因標籤的計數器。
-
★ 可疑時改成「導流」而非「丟棄」(繞道)——留著但不進主流程。
-
★ 過濾條件會累積成沒人敢改的一團。每個條件旁註記「為什麼」與「何時可拿掉」。
-
★ 不要在多處過濾。散落三個地方時,「這筆為什麼沒到」要查三次。
-
消費端過濾的成本可以估算(訊息大小 × 速率 × 丟棄比例)。用數字決定要不要加元件,不要憑感覺。
-
★ 不要和 內容過濾器 搞混:那個移除欄位,這個丟掉整則訊息。
🔗 相關工具
- 內容路由器 Content-Based Router(選目的地 vs. 過濾器只決定過或不過)
- 動態路由器 Dynamic Router(過濾/路由規則可動態設定)
- 企業整合模式
- 內容路由器 —— 不符條件時有另一個目的地
- 選擇性消費者 —— 消費端過濾
- 繞道 —— ★ 導流而非丟棄
- 內容過濾器 —— ★ 名字像但是移除欄位
- 訊息路由器 —— 家族總覽