事件匯流排架構 —— 總覽
內部工程文件
服務以 HTTP 發布一則業務事件,它會成為一張資料表,有權限的人就查得到。完整設計 —— 認證全路徑、政策來源、提交協定、schema 規則 —— 在 Event Bus repository 的六份文件裡, 連結列在最下方。這一頁只講形狀,因此只有一個來源,不會有第二份。
這張圖說了什麼
身分不換手。 發布走 HTTP,但端點把呼叫者的 token 原封不動轉給 Kafka,所以 broker 授權的是 真正的發布者,不是中間的 proxy。這條路上沒有任何一段重新簽發、替換身分,或把多個身分併成一個 共用的服務帳號。
授權只判一次。 broker 是唯一的執行點,它去問旁邊的政策引擎。沒有第二處也在決定存取, 因此也沒有第二處會與它不同步。
控制面是 git。 一個 topic 的所有事實 —— schema、誰可以發布、誰可以讀取 —— 都寫在同一份 檔案。schema、授權資料與落地資料表全都由那份檔案產生,不手改,每次變更都走 merge request。 政策本身完全不出現服務名稱;名字住在 data 裡。
落地剛好一次。 sink 在同一個交易裡提交事件與 offset,寫到一半當掉不會重複、也不會遺漏。
已知限制
這是團隊認為在相信其他任何部分之前應該先知道的四項。此處照原文件的講法記錄,沒有淡化。
| 限制 | |
|---|---|
| 🔴 | schema 驗證可以被繞過。 要不要驗證由呼叫端的 Content-Type 決定,而且沒有伺服器端設定可以強制。這是已接受的風險,以 dead-letter queue 與對帳處理,而不是從源頭擋掉。 |
| 🔴 | broker 的 healthcheck 會騙人。 它走內部 listener、以 super user 身分執行,在 authorizer 被呼叫之前就短路。實測:授權完全壞掉、每個請求都被拒絕時,broker 仍回報 healthy。只看 broker 健康狀態的監控看不到這種故障。 |
| 🔴 | 撤銷不是即時的。 資安事件不能只靠改授權資料處理,憑證本身也要一起處理。 |
| 🔴 | consumer group 沒登記,在 assign 型的消費端上是無聲的。 自己指派 partition 的用戶端會照常收到資料、看起來健康,只有 offset 回寫失敗(WARN)。那個 group 在 broker 上根本不存在,所以 lag 監控全盲,重啟會從頭重跑。 |
關於無聲的資料遺失。 過去有兩種形狀會在 Kafka 與資料表之間掉內容,而且不報錯、 不進死信佇列、對帳數字還是對的:自由格式 JSON,以及 schema 未宣告的鍵。兩者現在都在 控制面就被擋下,進不了 topic —— 這也是它們不再列在上面那四項的原因。 🔴 但這不等於風險消失了。 防線只有一條 lint 規則,可以豁免,而豁免是控制面的性質、 不是叢集上的性質:broker 與落地端都不會攔下一個已豁免的 topic 無聲掉內容。 另一條無聲遺失的途徑是一個維運動作,說明在提交協定那一份。
相關工作
| 項目 | 里程碑 |
|---|---|
| 28 · 事件匯流排(Kafka) | 資料平台里程碑 |
把事件在三站之間搬運也屬於本項目 —— 鏡像、各站各自落地,以及必須在第一條邊 開始載流量之前就到位的延遲監控。它如何嵌進三站的形狀,見 資料平台架構。
六份文件
每一項結論都是對實際跑起來的系統打出來的,不是照官方文件推測。最後查證 2026-08-27。
- 總覽 —— 入口:這套系統在做什麼、哪一份文件回答什麼
- 發布與消費 —— 認證:一把私鑰怎麼變成 token,token 怎麼原封不動抵達 broker
- 授權設計 —— 政策與三份資料檔、一次授權查詢如何被評估、以及撤銷延遲
- 從 topic 到表 —— 一條落地線由什麼組成,以及每個名字是怎麼推導出來的
- 提交協定 —— 「剛好一次」到底怎麼做到,以及儲存寫到一半失敗會怎樣
- Schema 撰寫指南 —— 寫一份的六條規則、怎麼改,以及三層型別系統對不上的地方