事件驅動架構——生產、發布、消費
在一張互動畫布上呈現事件驅動架構:生產者、事件匯流排、訂閱者與事件儲存,以及解耦如何讓新的消費者在不觸碰生產者的情況下加入。
事件驅動架構讓系統之間透過事件溝通,從而達致解耦:生產者發布已經發生的事,匯流排把它路由給訂閱者,而事件儲存則保留歷史。
事件驅動架構——生產、發布、消費
The interactive FlowJam canvas for this explanation — every lane, row and arrow above is a real QueryChart diagram you can open and edit.
How to read this visual
- 由左至右讀:發出、發布、消費與保留。
- 生產者那一列從來不會指向任何消費者——每一個箭頭都穿過匯流排,這就是把解耦畫了出來。
- 底下那條分支就是事件儲存:那些被即時消費的同一批事件,同時也被保留下來以供重播與審計。
生產與發布
「服務生產領域事件」就是生產者的全部責任——記錄某件事已經發生。「事件被發布到匯流排」與「匯流排把事件路由給訂閱者」是發布這一步:匯流排接收事件,並把它們送交每一個訂閱了的對象。發出那個方框上的備註把規則寫得很明白——生產者並不知道誰在聆聽,而這正是令系統可以擴充的原因。
即時消費
「消費者以非同步方式處理事件」是右邊那條路徑:訂閱者按自己的節奏對每一個事件作出行動——更新一個讀取模型、寄出一封電郵、觸發一個工作流程。非同步的處理,正是一個慢的消費者不會拖慢生產者的原因,也是圖解把兩者放在不同帶上的原因。
保留歷史
「事件儲存保留完整歷史」按次序記錄每一個事件,而「事件可以重播以供審計或復原」就是這份紀錄的用途——重建一個狀態、回答一條審計問題,或者用過去的事件餵養一個新的消費者。「新的消費者加入時無需觸碰生產者」是這套架構的試金石:因為歷史存在,而匯流排是按訂閱來路由,加入一項服務不會改動上游任何東西。
Key relationships and takeaways
- 事件記錄的是已經發生的事;它並不是給任何特定對象的命令。
- 匯流排把生產者與消費者解耦——雙方都不知道對方的身分或時間表。
- 事件儲存把歷史變成一份可以重播的權威紀錄。
- 消費者是非同步的:一個慢的消費者永遠不會阻塞生產者。
- 新的消費者靠訂閱就能加入——這套架構關於彈性的全部主張都建立在這一點之上。
When to use this visual
- 向一個正由請求/回應轉向事件的團隊,講解生產者、匯流排、消費者這個分工。
- 設計一項新的整合:事件儲存回答的是歷史需要保留下來,還是消費完就可以忘記。
- 覆核一個既有的事件驅動系統,找出那個經典的失誤——一個實際上是同步依賴的消費者。
運作方式
把各方改名成你自己的系統
把生產者、消費者與事件名稱換成你真實的服務,以及它們所發布的事件,並補上這張通用圖未涵蓋的部分。
為主題以及它們的消費者命名
在匯流排上為每一個事件標註主題名稱與訂閱者,令解耦成為一份寫下來的地圖,而不是一句斷言。
加入故障分支
插入匯流排停擺、消費者處理到一半死掉、或者同一個事件送達兩次時會發生甚麼——每一種都附上處理它的冪等或重試機制。
擴充事件儲存
加上你的系統實際採用的保留與重播規則——歷史保存多久、哪些狀態由它重建——好讓儲存那一帶反映你的政策。
常見問題
甚麼是事件驅動架構?
這是一種架構風格:各個組件以發布與訂閱事件的方式溝通,而不是直接互相呼叫。一項建立或改動了甚麼的服務,會發布一個描述已發生之事的事件;匯流排把它路由給每一個在意的訂閱者;而事件儲存則保留歷史。因為生產者從來不點名它的消費者,系統可以在不觸碰既有部分的情況下成長。
命令與事件有甚麼分別?
命令是一項指向特定接收者的指令——「處理這張訂單」——而且它期待一個結果。事件則是一份記錄,說明某件事已經發生——「訂單已建立」——而且它不點名任何接收者。這個分別之所以重要,是因為命令把發送方耦合到接收方,而事件則讓接收方保有改變的自由。圖解中的生產者永遠只發出事件,這正是令匯流排保持鬆散的原因。
事件儲存是用來做甚麼的?
事件儲存是系統保留下來的歷史:每一個事件,按次序,永久保存。它有三個用途——審計(發生了甚麼、何時發生)、復原(透過重播事件重建一項服務的狀態),以及可擴充性(一個新的消費者可以靠讀取過去來追上進度)。圖解把它畫成底下那條分支,因為它是對消費者即時處理的同一批事件的另一種用法。
事件驅動架構有哪些故障模式?
經典的幾種是:事件被送達多於一次(所以消費者必須是冪等的)、事件被亂序處理(所以消費者必須處理次序),以及死信佇列(那些一再失敗的事件)。圖解中的非同步處理正是令這些情況可以管理的原因——消費者可以重試而不會阻塞生產者——這也是為甚麼操作步驟裡那些故障分支,是這個設計實務上的另一半。
用 QueryChart(FlowJam)編輯這張圖解
把上面這張事件驅動畫布開啟為你自己的圖表——把生產者與消費者改名成你的服務,並把你的事件畫出來。