“訊息驅動、事件驅動、流 ”基礎概念解析

阿里巴巴雲原生發表於2022-04-26

*作者:肯夢*


> 阿里雲訊息佇列 RocketMQ 5.0 實現了全新升級,實現了從“訊息”到“訊息、事件、流”的大融合,基於此,Message-Driven、Event-Driven、Streaming 這三個詞是近期訊息領域高頻詞,但由於概念過於新,很多同學其實是不太理解這裡的異同。本文把三個概念重新整理下,梳理出比較明確的概念講給大家。


## 背景


首先這三個概念具體翻譯如下:


-   **Message-Driven:** 訊息驅動的通訊;

-   **Event- Driven:** 事件驅動的通訊;

-   **Streaming:** 流模式。


這三個模式都是類似非同步通訊的模式,傳送訊息的服務不會等待消費訊息服務響應任何資料,做服務解耦是三個模式共同的特性;


只要是在服務通訊領域內,在選型時還要考慮如下特性:


-   **排序:** 是否可以保證特定的順序交付;

-   **事務:** 生產者或消費者是否可以參與分散式事務;

-   **持久化:** 資料如何被持久化,以及是否可以重放資料;

-   **訂閱過濾:** 是否擁有根據Tag或其他欄位做訂閱過濾的能力;

-   At – least -once(最少交付一次),At-most-once(最多交付一次),Exactly-once (精確交付)。


通用背景介紹完,依次來看看各個模型代表的是什麼意思。


## 訊息驅動 Message-Driven


在訊息驅動通訊中,一般鏈路就是訊息生產者(Producer)向訊息消費者(Consumer)傳送訊息。模型如下:


![1.jpeg](~tplv-k3u1fbpfcp-zoom-1.image "1.jpeg")


訊息驅動模式下通常會用到中介軟體,比較常見的中間元件有 RocketMQ,Kafka,RabbitMQ 等。這些中介軟體的目的是快取生產者投遞的訊息直到消費者準備接收這些訊息,以此將兩端系統解耦。


在訊息驅動架構中,訊息的格式是基於消費者的需求制定的;訊息傳遞可以是一對一,多對多,一對多或多對一。


訊息驅動通訊比較常見的一個例子是商品訂單推送,上游元件負責生成訂單,下游元件負責接收訂單並處理。透過這樣的通訊方式上游生成元件其實無需關心整個訂單的生命週期,更專注於如何快速生成訂單,使單個元件的效能得以提升。!


![2.png](~tplv-k3u1fbpfcp-zoom-1.image "2.png")


訊息驅動模式在服務之間提供了輕的耦合(這部分耦合指代 Producer/Consumer SDK),並可以對生產和消費服務根據訴求進行擴充套件。


## 事件驅動 Event-Driven


首先要申明一個觀點:事件驅動其實是對訊息驅動方法的改進,它對訊息體大小,訊息格式做了較為嚴格的限制,這層基於訊息的限制封裝其實就稱為事件(Event)。


在事件驅動模式中,生產者釋出事件來表示系統變更,任何感興趣且有許可權接入的服務都可以訂閱這些事件,並將這些事件作為觸發器來啟動某些邏輯/儲存/任務。


![3.jpeg](~tplv-k3u1fbpfcp-zoom-1.image "3.jpeg")


事件驅動的模式可以是一對一,多對一,一對多或多對多。通常情況下一般是多個目標根據過濾條件執行不同的事件。


在事件驅動架構中,事件的格式是由生產者根據事件標準協議制定的;由於更規範限制和封裝,事件的生產者完全不需要關心有哪些系統正在消費它生成的事件。


事件不是命令,事件不會告訴消費者如何處理資訊,他們的作用只是告訴消費者此時此刻有個事件發生了;事件是一份不可變的資料,重要的資料,它與訊息的資料價值相同;通常情況下當某個事件發生並執行時,往往伴隨著另一個事件的產生。


事件驅動提供了服務間的最小耦合,並允許生產服務和消費服務根據需求進行擴充套件;事件驅動可以在不影響現有服務的情況下新增各類新增元件。


事件驅動也可以舉一個非常貼切的例子,我們以“客戶購買完一款商品”為一個事件,舉證在事件場景的應用:


-   CRM(客戶關係系統)系統接收到客戶購買資訊,可自行更新客戶的購買記錄;

-   EMR(庫存管理系統) 系統接收到客戶購買資訊,動態調整庫存並及時補貨;

-   快遞服務接收到客戶購買資訊,自行打單並通知快遞公司派送。


這麼看,事件驅動模式是不是可以應用並出現在任何地方!


在 EventBridge 產品化方向,也正是由於針對訊息做了一些標準化封裝,才有可能實現譬如針對事件本身的 filter(過濾) ,transform(轉換),schema(事件結構),search(查詢) 等能力。這些能力也擴充出更多針對事件驅動特有的場景功能及相關特性。


## 流 Streaming

流是一組有序的無界事件或資料,執行操作通常是固定的某個事件段(e.g. 00:00 – 12:00)或一個相對事件(E.g. 過去 12 小時)。


![4.jpeg](~tplv-k3u1fbpfcp-zoom-1.image "4.jpeg")


通常情況下單個事件往往就是使用事件本身,但是對於流可能的操作大機率是過濾,組合,拆分,對映等等。


流的操作可以是無狀態也可以是有狀態的:


-   對於單個事件操作是無狀態的,包括過濾和對映;

-   依賴訊息在流的時間或位置(e.g. offset,time)是有狀態的。有狀態操作中,流處理邏輯必須保留一些已被消費訊息的記憶體。有狀態包括對資料做 Batch Size,Batch Window 等。


流這裡也可以舉一個比較簡單的例子,比如我們的物流系統在物品透過一個物流節點時會生成一個事件,但是要查到這個物品完整的流轉狀態事件,則必須是各個物流節點單個事件的聚合,那這個聚合事件就是流事件。


Kafka 是最典型的流式中介軟體,在流式場景中,事件的位置資訊至關重要。通常情況下位置資訊(E.g. offset)是由消費者託管的。


## 事件規範標準


聊完 Event 和 Streaming 是什麼,再來補充一點有關於它們的規範。


事件規範存在的目的是為了清晰事件生產者和消費者的關係,目前主要有兩部分:AsyncAPI 和 CloudEvents;


**AsyncAPI:** 基於事件 API 提供了與之對應的 Open API 和 Swagger 等;**CloudEvents:** 側重於處理事件的後設資料。


下面也重點介紹一些關於 CloudEvents 的相關概念參考:CloudEvents 的核心其實是定義了一組關於不同元件間傳輸事件的後設資料,以及這些後設資料應該如何出現在訊息體中。


其主旨大抵如下:


-   事件規範化;

-   降低平臺整合難度;

-   提高 FaaS 的可移植性;

-   源事件可追蹤;

-   提升事件關聯性


準確的事件體,事件資訊才可以做出更穩定的系統架構,永遠保持對事件的敬畏。


**附 一些術語及定義:**


**Occurrence:** 發生,指事件邏輯上的發生,基於某種情況,事件出現了;


**Event:** 事件,表示事件以及上下文的資料記錄。可以根據事件中的資訊決定路由,但事件本身並不包含路由資訊;


**Producer:** 生產者,真正創造事件的例項或元件;


**Source:** 源,事件發生的上下文,可以由多個 producer 組成;


**Consumer:** 消費者,接收事件並對事件進行消費;


**Intermediary**:中介,接收包含事件的訊息(message),並轉發給下一個接收方,類似路由器;


**Context:** 上下文,上下文後設資料被封裝到 context attributes 中,用來判斷事件與其它系統的關係;


**Data:** 資料,也可以叫做 payload;


**EventFormat**:事件格式,例如 json;


**Message:** 訊息,封裝事件並將其從 source 傳遞到 destination;


**Protocol:** 協議,可以是行業標準如 http,開源協議如 Kafka 或者供應商協議如 AWS Kinesis;


**Protocol Binding:** 協議繫結,描述如何透過給定的協議收發事件,如何將事件放到訊息裡。


## 重磅推薦


本文旨在幫助大家對近期訊息領域的高頻詞“訊息驅動(Message-Driven),事件驅動(Event-Driven)和流(Streaming)”有更清晰的瞭解和認知,其中事件驅動 EDA 作為 Gartner 預測的十大技術趨勢之一, EventBridge 作為下一代訊息中介軟體,也是目前的重點方向之一。如果大家感興趣,想要有更多瞭解,可關注**「阿里雲 EventBridge 系列公開課」**,完整課程正火熱開講中!


![5.png](~tplv-k3u1fbpfcp-zoom-1.image "5.png")


點選[**此處**](),可以直接觀看課程影片~


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69953029/viewspace-2888913/,如需轉載,請註明出處,否則將追究法律責任。

相關文章