當一個產品從單一應用成長為多個服務、多端客戶端和後台任務共同協作的系統時,同步調用很快會暴露出限制。 一個訂單完成、一次訓練導入、一條內容發佈,往往會觸發通知、統計、推薦、審計、緩存刷新等多個後續動作。 如果所有動作都寫在同一條調用鏈里,系統會變得脆弱且難以擴展。
先定義業務事實,而不是技術消息
好的事件命名應該描述已經發生的業務事實,例如“訓練已導入”“賬號已綁定”“視頻已完成導出”。 它不是命令,也不是某個服務內部函數的遠程版本。事件一旦發佈,訂閱方可以根據自己的上下文決定如何響應。
這也是事件驅動架構和普通消息隊列用法的區別。前者關注長期業務語義,後者可能只是把一次異步任務放到後台執行。 如果事件只反映技術動作,系統很容易在幾次迭代後失去可讀性。
事件粒度要服務於演進
粒度過粗會讓訂閱方必須解析大量無關字段,粒度過細又會讓事件流變得噪聲過多。實踐中可以從用戶可感知的狀態變化開始建模, 再根據業務邊界拆分事件。一個事件應該足以說明“什麼對象在什麼時刻發生了什麼變化”,但不必攜帶所有派生數據。
對於核心事件,建議使用穩定的事件名、版本號、發生時間、唯一事件 ID、關聯對象 ID 和來源信息。 這些字段看似基礎,卻決定了後續排查、回放、重試和審計能否順利進行。
冪等與重試是默認要求
事件系統不應該假設消息只會被處理一次。網絡抖動、消費者重啓、超時重試、批處理恢復都可能帶來重復事件。 每個訂閱方都需要基於事件 ID 或業務唯一鍵實現冪等處理,讓重復消費不會造成重復扣費、重復通知或重復寫入。
重試策略也要分層處理。臨時錯誤可以延遲重試,數據錯誤應該進入死信隊列並提供人工處理入口。 如果所有異常都無限重試,系統會把一個小問題放大成持續的資源浪費。
可觀測性決定維護成本
事件驅動架構把流程拆散了,因此更需要把鏈路重新看見。每個事件從發佈、投遞、消費到最終處理結果,都應該能被查詢。 對用戶可見的關鍵流程,還需要統一的追蹤 ID,讓客服、運營和工程團隊能圍繞同一個事實排查問題。
日誌只是第一步。更成熟的系統會提供事件面板、消費延遲、失敗率、死信數量和訂閱方健康度。 當事件成為系統骨架,可觀測性就不再是附加功能,而是基礎設施。
從保守設計開始
事件驅動並不意味著一開始就引入複雜平台。很多團隊可以先從少量核心事件、明確的事件表和後台 worker 開始, 等業務邊界穩定後再遷移到專門的消息中間件或事件總線。
最重要的是保持事件語義清晰、處理邏輯冪等、失敗路徑可恢復。技術選型會變化,但這些原則能讓系統在增長過程中保持彈性。