事件驅動架構近年來已成為開發高度可擴展分散式系統的非常流行的選擇。是一種軟體設計方式,其中系統的不同部分透過發送和回應事件進行通訊。
事件就是發生的事情,例如:
用戶註冊
用戶上傳照片
付款已完成
系統的不同部分不是直接向彼此發出請求,而是監聽這些事件並在需要時(非同步)做出反應。
例如:
支付服務已完成並發出事件:「支付完成」。
庫存服務監聽該事件並更新已購買的新產品的庫存。
電子郵件服務監聽並傳送確認電子郵件。
讓我們來看看事件驅動架構中元件的簡單圖表
1. 活動製作人/發布者
當某些事情發生時建立並發出事件的系統或服務。
範例:當新用戶註冊時,用戶服務會發送「用戶已註冊」事件。
2. 訊息代理
訊息代理人是一種充當事件生產者和事件消費者之間的中介的中間件。其主要作用是有效率地接收、儲存和路由事件,確保事件傳遞給正確的消費者服務。
在這個背景下,訊息代理內部有一個關鍵的概念,稱為「頻道」 。這些管道充當溝通路線,協調事件從生產者到正確消費者的流。
在Kafka中,這些管道被稱為主題 (Topic) 。它支援多訂閱者模型,允許多個消費者監聽同一個發布者。
在RabbitMQ中,這些通道稱為佇列。 RabbitMQ 通常是點對點的佇列,這意味著只有一個消費者可以處理來自佇列的訊息。
範例技術:Kafka、RabbitMQ、AWS SNS/SQS、Google Pub/Sub。
3. 事件消費者/訂閱者
監聽事件並對其做出反應的服務。
範例:通知服務監聽「使用者已註冊」並發送歡迎電子郵件。
4. 活動
描述所發生情況的實際訊息。它通常包含結構化資料(JSON、XML)。
事件訊息範例:
{
"data": {
"id": "event-123456",
"type": "user.event.registered",
"timestamp": "2025-04-01T12:00",
"attributes": {
"id": "usr-98765",
"email": "[email protected]",
"surname": "example",
}
}
}
在訊息代理程式中,交換是一種路由機制,它決定了訊息如何傳遞到佇列。不同類型的交易所提供不同的訊息分發模式。
直接交換(1:1 路由)
根據路由鍵和佇列綁定鍵(RabbitMQ)之間的精確匹配將訊息路由到佇列。
它是如何運作的?
生產者發送一條帶有路由鍵的訊息。
交換器僅將訊息轉送到具有匹配綁定鍵的佇列。
例子:
帶有路由鍵 = "order.created"
的訊息僅進入與"order.created"
綁定的佇列。
扇出交換(廣播)
將訊息傳送到所有綁定佇列,忽略路由鍵
(RabbitMQ-Fanout Exchange | Kafka-每個主題有多位消費者)。
它是如何運作的?
生產者發送一條訊息。
交換器將訊息複製到與其綁定的所有佇列。
例子:
通知事件被廣播到多個服務(電子郵件、簡訊、推播通知)。
主題交換(模式匹配)
根據路由鍵中的通配符模式來路由訊息。支持*
,匹配一個單字和#
,匹配多個單字。 (RabbitMQ-主題交換 | 帶有分區鍵的 Kafka 主題)。
它是如何運作的?
.
在路由鍵( "order.payment.failed"
)中分隔單字。例子:
綁定到"order.*"
佇列接收"order.created"
和"order.cancelled"
,但不接收"user.created"
。
可擴展性:解耦的服務可以獨立擴展。
靈活性:無需修改現有服務即可輕鬆新增新的事件消費者。
即時處理:實現即時資料流和快速回應。
彈性:只要事件和訂閱得到妥善管理,服務的故障就不會影響整個系統
鬆散耦合:元件透過事件進行交互,減少依賴。
最終一致性:系統的不同部分可能暫時擁有過時的訊息,直到所有事件都被處理。
複雜的除錯:跨多個非同步事件追蹤問題更加困難。
增加延遲:由於非同步特性,某些事件可能需要更長時間才能處理。
事件重複:需要冪等性以避免重複處理。
事件排序問題:有些代理不保證訊息順序(RabbitMQ)。
學習曲線:需要事件驅動設計模式的專業知識。
如果您正在考慮實現分散式、即時且高度可擴展的系統,那麼您絕對應該考慮實現事件驅動的架構,以充分利用它提供的所有優勢。
原文出處:https://dev.to/jhonifaber/introduction-to-event-driven-architecture-eda-3ioj