RocketMQ EventBridge 簡介
RocketMQ EventBridge 致力於協助使用者建構高可靠性、低耦合和高性能的事件驅動架構。在事件驅動架構中,微服務不需要主動訂閱外部訊息,而是可以將觸發微服務系統變更的所有項目集中到 API,並且只需要專注於目前微服務自己的業務網域模型定義和 API 設計,而不需要透過大量膠水程式碼來調整和解析外部服務訊息。EventBridge 負責安全且可靠地調整和傳遞外部服務產生的事件到目前微服務設計的 API。
我們什麼時候使用 RocketMQ 訊息,什麼時候使用 EventBridge 事件?事件的意義是什麼,與訊息有什麼不同?
訊息與事件
我們已將事件定義如下
Events refer to things that have already happened, especially important things.
事件與訊息之間的關係如下:
訊息包括命令訊息和事件訊息。命令訊息是由外部系統傳送給此系統的操作命令(如圖中左側所示);事件訊息是在系統收到命令操作要求並進行內部變更後發生的事件(如圖中右側所示);
事件的四個特徵
1. 已發生
事件總是「已經發生」的。「已經發生」也意味著它們是不可變的。這個特性非常重要,當我們處理事件和分析事件時,這意味著我們可以絕對信任這些事件,只要我們收到了事件,它們就一定是系統的真實行為。
命令表示一個操作請求,它是否真的發生了是無法知道的。例如:
* Turning on the kitchen lights
* Someone pressed the doorbell
* Account A received 100,000.
事件是一個已經發生的明確發生,例如
* The kitchen light being turned on
* Someone pressing the doorbell
* Account A receiving 100,000
2. 沒有期待
An event is an objective description of a change in the state or attribute value of a thing, but it does not make any expectations about how to handle the event itself. In contrast, both Command and Query have expectations, they hope the system will make changes or return results, but the Event is just an objective description of a change in the system.
例如:交通號誌,從綠色變成黃色,只是描述一個客觀事實,本身沒有客觀的期待。在不同的國家和地區,對這個事件賦予了不同的期待。例如,在日本,黃色等於紅色,而在俄羅斯,闖黃燈是可以容忍的。
與命令訊息相比:
- 事件:有點像「市場經濟」,商品生產出來擺在商場的大櫥窗裡,消費者覺得好就買回去,如果沒人買,商品可能過期浪費掉。
- 命令訊息:有點像「計畫經濟」,生產是根據需求,指定分配對象,很少有浪費。
3. 自然有序且唯一
The same entity cannot have both A and B occur at the same time, there must be a temporal relationship; if so, these two events must belong to different event types.
例如:對於同一個交通號誌,它不可能同時變成綠色和紅色,它在某個時刻只能變成一種狀態。如果我們看到兩個內容相同的事件,那麼它一定是發生了兩次,而且一次發生在另一次之前。這對於處理資料一致性和系統行為分析(例如 ABA 場景)很有價值:我們不僅看到系統的最終結果,還看到導致該結果的中間過程。
4. 實體化
事件盡可能完整地記錄「犯罪現場」,因為事件不知道消費者會如何使用它們,所以它們會盡可能詳細。包括
When did the event occur?
Who generated it?
What type of event is it?
What is the content of the event? What is the structure of the content?
... ...
相較於我們常見的消息,由於上游和下游一般是確定的,往往為了提升效能和傳輸效率,消息會盡可能精簡,只要滿足「計畫經濟」下消費者規定的需求即可。
RocketMQ EventBridge 的典型應用場景
場景一:事件通知
在微服務中,我們經常會遇到一種情況,一個微服務產生的消息,需要通知到其他消費者。這裡我們對比三種方式
A:強依賴方式
生產者主動調用消費者的微服務,適配消費者的 API。這種設計無疑是非常糟糕的,生產者對消費者強依賴,耦合度極深。如果調用消費者出現異常,沒有做有效的隔離,極有可能導致整個微服務掛掉。當有新的消費者進來時,擴充性非常差。
B:半解耦方式
生產者將消息發送到消息服務,消費者訂閱消息服務獲取消息,並將消息轉換成自己業務領域模型所需要的資料格式。這種方式在調用鏈路上實現了解耦,極大降低了系統風險,但是對於消費者來說,仍然需要理解和解析生產者的業務語義,並將消息轉換成自己業務領域需要的格式。在這種方式下,當消費者需要訂閱多個生產者的資料時,需要大量的膠水程式碼去適配生產者產生的每條消息。另外,當上游生產者的消息格式發生變化時,也存在風險和運維成本。
C:完全解耦方式
在這種方式下,消費者無需引入 SDK 即可訂閱 Broker,只需根據自己的業務領域模型設計 API,消息服務會在上游進行過濾、轉換
場景二:系統間集成
場景一主要關注於單個產品內部微服務之間的事件溝通,場景二主要關注於多個產品之間的事件溝通。在一個企業中,我們往往會使用多個產品,而這些產品中有許多可能並非我們自己研發,而是採購的外部 SaaS 服務。這種情況下,不同外部 SaaS 產品之間的事件流轉會比較困難,因為這些外部 SaaS 產品並非我們自己研發,不便於修改其代碼。EventBridge 提供的事件中心能力,可以幫助收集各個產品產生的事件,並將其很好的組織管理起來,就像百貨商場的櫥窗一樣,將商品精心陳列,並附上說明,供消費者挑選,同時還提供送貨上門服務。
RocketMQ EventBridge 是如何工作的?
為了解決上述兩個場景中提到的問題,EventBridge 從五個方面入手
1. 制定事件標準
因為事件並不是為自己服務的,而是為大家服務的。它沒有明確的消費者,所有都是潛在的消費者。因此,我們需要對事件的定義進行標準化,這樣大家才能看懂,容易理解。目前,CNCF 旗下的 CloudEvent 逐漸成為廣泛認可的事實標準,因此我們選擇 CloudEvent 作為 EventBridge 的事件標準。
2. 建立事件中心
事件中心包含了各個系統註冊的所有事件。這就像我們上面提到的市場經濟百貨商場,將各種事件分類陳列,大家可以進來看看有哪些事件可能需要,然後再買回去。
3. 定義事件格式
事件格式用於描述事件的具體內容。這相當於市場經濟中的買賣合同。生產者發送的事件格式必須確定,不能隨意更改;消費者接收事件的格式也必須確定,否則整個市場將會混亂。
4. 訂閱「規則」
我們需要讓消費者能夠將事件傳遞到目標端,並在傳遞前過濾和轉換事件,以便它能適應目標端 API 接收參數的格式。我們稱此程序為建立訂閱規則。
5. 事件匯流排:最後,我們還需要一個地方來儲存事件,也就是圖表中間的事件匯流排。