概述#
Event-driven architecture 是一種流行的分散式非同步架構風格,用於建構高可擴展性和高效能的應用程式。它由解耦的事件處理元件(event processing components)組成,非同步地接收和處理事件。可作為獨立架構風格使用,也可嵌入其他架構中(如 event-driven microservices)。
Request-Based vs. Event-Based 模型#
大多數應用遵循 request-based(請求式)模型:
- 請求發送至 request orchestrator(通常是 UI 或 API 層)
- Orchestrator 確定性地、同步地將請求導向各 request processors
Event-based(事件式)模型則不同:
- 系統對特定情境做出反應並採取行動
- 例如:線上拍賣中的出價是一個「事件」,不是對系統的「請求」
拓樸概覽(Topology)#
Event-driven architecture 有兩種主要拓樸:
- Mediator topology — 需要控制事件處理的工作流程時使用
- Broker topology — 需要高度回應性和動態控制事件處理時使用
兩種拓樸的架構特性和實作策略不同,因此理解各自適用場景非常重要。
Broker Topology#
Broker topology 的特點是沒有中央事件協調者。訊息流以鏈式廣播方式分布在各 event processor 之間,透過輕量級 message broker(如 RabbitMQ、ActiveMQ、HornetQ 等)傳遞。
四個主要元件#
- Initiating event — 啟動整個事件流程的初始事件
- Event broker — 事件通道(event channel),接收事件以供處理
- Event processor — 接受並處理事件的元件,完成後產生 processing event
- Processing event — 非同步地發送至 event broker,供其他 event processor 監聽和回應

Figure 14.2: Broker topology
處理流程(以線上書店訂單為例)#
- PlaceOrder(initiating event)→ OrderPlacement processor 建立訂單、插入資料庫、回傳 order ID
- OrderPlacement 發出 order-created processing event
- 三個 processor 平行回應:Notification(寄 email)、Payment(收款)、Inventory(扣庫存)
- Payment 產生 payment-applied 和 payment-denied 兩種事件
- Inventory 產生 inventory-updated → Warehouse processor 回應
- OrderFulfillment 監聽 payment-applied → 產生 order-fulfilled
- Notification 和 Shipping 監聽 order-fulfilled → 通知客戶並出貨
在 broker topology 中,每個 event processor 都應廣告(advertise)其完成的動作,無論是否有其他 processor 關心。這提供了架構擴展性(architectural extensibility)——未來可輕鬆加入新的 processor 來監聽現有事件。

Figure 14.3: Notification event is sent but ignored

Figure 14.4: Example of the broker topology
優缺點#
| 優點 | 缺點 |
|---|---|
| 高度解耦的 event processors | 缺乏工作流程控制 |
| 高可擴展性 | 錯誤處理困難 |
| 高回應性 | 缺乏可恢復性(recoverability) |
| 高效能 | 無法重新啟動交易 |
| 高容錯能力 | 資料不一致性 |
Mediator Topology#
Mediator topology 透過一個事件協調者(event mediator)來管理和控制事件處理工作流程,解決 broker topology 的缺點。
五個主要元件#
- Initiating event — 啟動事件流程
- Event queue — 接收 initiating event 的佇列
- Event mediator — 了解處理步驟,產生對應的 processing events
- Event channels — 通常是 point-to-point 的 queues(非 topics)
- Event processors — 監聽 event channels,處理事件後回覆 mediator

Figure 14.5: Mediator topology
Mediator 實作層級#
根據事件的性質和複雜度,mediator 有不同的實作選擇:
- 簡單事件 — 使用 Apache Camel、Mule ESB 或 Spring Integration,透過程式碼控制 message flow
- 困難事件(多條件、多路徑、錯誤處理)— 使用 Apache ODE 或 Oracle BPEL Process Manager,以 BPEL 描述處理步驟
- 複雜事件(需要人工介入、長時間運行)— 使用 Business Process Management(BPM)引擎如 jBPM
建議將所有事件先路由到一個簡單 mediator(如 Apache Camel),由它分類事件:簡單事件自行處理,困難或複雜事件則轉發給對應的 BPEL 或 BPM mediator。

Figure 14.6: Delegating the event to the appropriate type of event mediator
處理流程(以線上書店訂單為例)#
Mediator 知道處理 PlaceOrder 事件的完整步驟:
- Step 1: Place Order — 發送 create-order 至 OrderPlacement processor

Figure 14.7: Mediator steps for placing an order
- Step 2: Process Order — 同時發送三個事件(email-customer、apply-payment、adjust-inventory),等待全部完成

Figure 14.9: Step 2 of the mediator example
- Step 3: Fulfill Order — 同時發送 fulfill-order 和 replenish-stock

Figure 14.10: Step 3 of the mediator example
- Step 4: Ship Order — 同時發送 email-customer(通知已準備出貨)和 ship-order

Figure 14.11: Step 4 of the mediator example
- Step 5: Notify Customer — 發送 email-customer(通知已出貨),工作流程完成

Figure 14.12: Step 5 of the mediator example
Processing events 的語意差異#
- Broker topology:processing events 是「已發生的事件」(events),如 order-created、payment-applied → 其他 processor 可忽略
- Mediator topology:processing events 是「需要執行的命令」(commands),如 place-order、send-email → processor 必須處理
優缺點#
| 優點 | 缺點 |
|---|---|
| 工作流程控制 | Event processors 耦合度較高 |
| 錯誤處理 | 較低的可擴展性 |
| 可恢復性 | 較低的效能 |
| 重新啟動能力 | 較低的容錯能力 |
| 更好的資料一致性 | 難以建模複雜工作流程 |
非同步能力(Asynchronous Capabilities)#
Event-driven architecture 的獨特特性在於完全依賴非同步通訊。這大幅提升了系統的 responsiveness(回應性),但不等於提升 performance(效能)。
以使用者發表評論為例:
- 同步方式:50ms(網路延遲)+ 3,000ms(處理)+ 50ms(回傳)= 3,100ms 回應時間
- 非同步方式:25ms(發送至 queue)+ 25ms(確認)= 25ms 回應時間(處理仍需 3,000ms,但使用者不必等待)
非同步通訊的主要問題是錯誤處理。使用者收到確認後若處理失敗,回傳錯誤變得困難。

Figure 14.13: Synchronous versus asynchronous communication
錯誤處理(Error Handling)#
Workflow event pattern 是一種 reactive architecture pattern,在不影響回應性的前提下處理非同步工作流程中的錯誤:
- Event producer 非同步地透過 message channel 將資料傳送至 event consumer
- 當 event consumer 遇到錯誤時,立即將錯誤委派給 workflow processor,然後繼續處理下一則訊息
- Workflow processor 嘗試程式化修復錯誤,修復後將訊息重新送回原始 queue
- 若無法修復,則送至 dashboard(類似郵件收件匣的應用),由人工檢視、修復並重新提交

Figure 14.14: Workflow event pattern of reactive architecture

Figure 14.15: Error handling with the workflow event pattern
Workflow event pattern 的一個後果是錯誤訊息重新處理時會亂序。可透過暫存相同 context(如相同帳號)的後續訊息來維持順序。
防止資料遺失(Preventing Data Loss)#
在 event-driven architecture 中,有三個可能發生資料遺失的地方:
- 訊息從 producer 到 queue 的過程中遺失 — 使用 synchronous send 搭配 persisted message queues(guaranteed delivery)解決
- Event processor 從 queue 取出訊息後 crash — 使用 client acknowledge mode(訊息留在 queue 直到確認處理完成)解決
- Event processor 無法將資料寫入資料庫 — 使用 ACID 交易搭配 last participant support(LPS)解決,確認資料庫 commit 後才從 queue 移除訊息

Figure 14.16: Where data loss can happen within an event-driven architecture
廣播能力(Broadcast Capabilities)#
Event-driven architecture 的獨特能力之一是廣播事件——producer 發布訊息時不知道(也不在乎)誰會接收和如何處理。這是 event processors 之間最高層級的解耦,也是實現 eventual consistency、complex event processing(CEP)等模式的關鍵。

Figure 14.18: Broadcasting events to other event processors
Request-Reply 模式#
當需要同步通訊時(如取得 order ID),可透過 request-reply messaging(又稱 pseudosynchronous communications)實現:
- 每個 event channel 包含一個 request queue 和一個 reply queue
- Producer 發送請求後在 reply queue 上做 blocking wait

Figure 14.19: Request-reply message processing
兩種實作技術#
- Correlation ID(推薦)— 在 reply message header 中設定 correlation ID = 原始 message ID,producer 透過 message selector 過濾

Figure 14.20: Request-reply message processing using a correlation ID
- Temporary queue — 為每個請求建立專屬的暫時 queue,較簡單但大量訊息時效能較差

Figure 14.21: Request-reply message processing using a temporary queue
選擇 Broker vs. Mediator#
選擇本質上是一個取捨:
- Broker — 優先考慮效能、可擴展性、容錯
- Mediator — 優先考慮工作流程控制、錯誤處理、可恢復性
混合 Event-Driven 架構(Hybrid Event-Driven Architectures)#
Event-driven architecture 經常與其他架構風格結合使用,形成混合架構:
- Event-driven microservices — 最常見的混合
- Event-driven space-based architecture — 用於 data pumps
- Event-driven microkernel — 為 plug-in 提供事件驅動能力
- Event-driven pipeline — 結合管道和事件處理
加入 event-driven 架構可以移除瓶頸、提供 back pressure point,以及提供其他架構風格所缺乏的使用者回應性。
架構特性評分(Architecture Characteristics Ratings)#
| 架構特性 | 評分 |
|---|---|
| Partitioning type | Technical |
| Number of quanta | 1 to many |
| Deployability | ★★★ |
| Elasticity | ★★★ |
| Evolutionary | ★★★★★ |
| Fault tolerance | ★★★★★ |
| Modularity | ★★★★ |
| Overall cost | ★★★ |
| Performance | ★★★★★ |
| Reliability | ★★★ |
| Scalability | ★★★★★ |
| Simplicity | ★ |
| Testability | ★★ |

Figure 14.22: Event-driven architecture characteristics ratings
評分解析#
- Performance / Scalability / Fault tolerance(5 星) — 非同步通訊搭配高度平行處理帶來高效能;透過 competing consumers 實現可程式化的負載平衡;高度解耦的 event processors 提供容錯能力
- Evolutionary(5 星) — 新增功能只需加入新的 event processor 或在 broker topology 中監聽現有事件即可
- Simplicity / Testability(1-2 星) — 非確定性和動態的事件流使得測試和理解系統非常困難,event tree diagrams 可能極度複雜
- Technical partitioning — 特定領域的功能分散在多個 event processors、mediators、queues 和 topics 中,因此不是 domain partitioned