天天看點

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

作者:技術聯盟總壇

沈林 阿裡雲雲原生 2023-06-15 18:30 發表于浙江

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

前言

Cloud Native

事件驅動,這個詞在部分人印象中,它是一個過時的技術——沒什麼新意。從時間上看,确實也是這樣,上世紀 60 年代,事件驅動就已經被正式提出,經常會被在 GUI 程式設計中。但是在有些人印象中,事件驅動又是一個非常陌生,非常新穎的技術。

不管怎麼樣,現實是已經有越來越多的公司,開始或則經把事件驅動架構應用到企業的核心業務中,包括:阿裡巴巴、喜力、聯合利華、美國聯邦航空管理局、銀行資本市場等等。市場上,也有很多公司推出了自己的産品或解決方案,比如阿裡雲、AWS、Google,Solace。行業裡也孕育出了事件的标準:CloudEventsGartener,則把事件驅動定義為未來十大趨勢之一;

這個時候,我們就要問了,事件驅動架構到底是什麼呢?為什麼現在,被越來越多的人,開始關注事件驅動架構了呢?

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

5 月 28 日,GOTC 2023 全球開源技術峰會上,阿裡雲智能技術專家沈林發表主題演講:Apache RocketMQ 事件驅動引擎。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

什麼是事件?

Cloud Native

說到事件驅動架構,大家第一印象往往會把重點放在“架構”這兩個字上,但是,事件驅動架構很大的魅力其實來源于前面“事件”兩個字,是以今天,我們先一起看下什麼是事件。RocketMQ 之前一直給人的印象是一個消息引擎,那為什麼我們在前段時間釋出的 5.0 版本中,引入了事件?消息跟事件,又有什麼差別呢?

事件,如果我們查閱字典,他會給你這樣一個解釋:事件是指過去已經發生的事,尤其是比較重要的事。

這個很好了解啊。比如,GOTC 大會今天在上海正式開幕了;剛才我的手機鈴聲響了;這些都是過去已經發生的事件。

但是,如果我們接着剛才的問題問:事件跟消息有什麼差別呢?這個時候,大家是不是覺得事件這個定義,好像又不那麼清晰了?剛才我們說的那些事件,是不是也可以了解為消息?如果這個時候,老張給我發送了一條短信,那這個短信,算是事件,還是消息呢?

我們可以通過這張圖,來簡單了解消息和事件的關系。消息包含兩類,一類是 Command 消息,另一類就是 Event 消息。

1、Command 消息是什麼?我們看下面左邊這張圖,外部系統發送給本系統的一條操作指令,就是Command消息;

2、那什麼是 Event 消息呢?再看下面右邊這張圖,本系統收到外部 Command 操作請求,系統内部發生改變之後,就産生了 Event;

是以,事件和消息稍微有些不同。事件,可以了解為是一種特殊的消息,那事件特殊在什麼地方呢?主要包含 4 個方面:

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

事件的特性 1:已發生且不可變的

事件,一定是“已發的”。“已發生”的代表什麼呢?不可變的。我們不可能改變過去,除非你有超能力。這個特性非常重要,在我們處理事件、分析事件的時候,這就意味着,我們絕對可以相信這些事件,隻要是收到的事件,一定是系統真實發生過的行為,而且是 Immutable,不可修改。

對比 Command 消息,Command 的中文是什麼?指令!很顯然,它還是沒有發生的,而是表達了一種期望。我們知道,“期望的”不一定會成功發生。比如:

  • 把廚房的燈打開;
  • 去按下門鈴;
  • 轉給 A 賬戶 10w;

這些都是 Commond,都是期望發生的行為。但是,最終有沒有發生呢?并不知道。

Event 則是明确已經發生的事情。比如:

  • 廚房燈被打開了;
  • 有人按了門鈴;
  • A 賬戶收到了 10w

事件的特性 2:無期望的

事件的第二個特性是:無期望的。事件是客觀的描述一個事物的狀态或屬性值的變化,但對于如何處理事件本身并沒有做任何期望。相比之下,Commond 則是有期望的,它希望系統做出改變;但是 Event,它隻是客觀描述系統的一個變化。我們舉一個例子:交通信号燈從綠燈變成紅燈,它就是一個事件。事件本身并沒有任何期望,說要求行人或汽車禁止通行,而是交通法規需要紅綠燈,并賦予了其規則。

是以,系統,一般不會定向的、單獨向一個指定的系統發送事件,而是統一的告訴“事件中心”。“事件中心”那裡面有各個系統上報上來的,各式各樣的事件。系統會向事件中心說明:自己這個系統,會産生哪些事件,這些事件的格式是怎麼樣的;别的系統如果感興趣,就可以來主動訂閱這些事件;真正賦予事件價值的,是事件消費者。事件消費者想看看,某個系統發生了什麼變化?OK,那他就去訂閱這些事件,是以事件是消費者驅動的。

這跟消息有什麼差別呢?Commond 消息的發送和訂閱,是雙方約定好的,外人不知道,往往是以文檔或代碼的形式,大家按約定好的協定,發送和訂閱消費,這個過程往往是生産者驅動的。

打個比喻,事件就像市場經濟,商品被生産出來,具體有什麼價值,有多大價值,很大程度上看其消費者。我們能看到系統中各種各樣的事件,就像櫥窗裡擺放了各種各樣的商品;而 Commond 消息,有點像計劃經濟,一出生就帶着很強的目的性,“我”就是要“配置設定”給誰消費。

事件的特性 3:天然有序且唯一的

事件的第三個特性是:“天然有序且唯一的”。同一個實體,不能同時發生 A 又發生 B,必有先後關系;如果是,則這兩個事件必屬于不同的事件類型。細心的同學,肯定發現了一點,這裡其實隐藏了事件的一個額外屬性:因為天然有序,跟時間軸上的某一時刻強綁定,且不能同時發生,是以它一定是唯一的。

如果我們看到了兩個内容一樣的事件,那麼一定是發生了兩次,而且一次在前,一次在後。這對于我們處理資料最終一緻性、以及系統行為分析都很有價值:我們看到的,不光是系統的一個最終結果,而是看到變成這個結果之前的,一系列中間過程。

事件的特性 4:具象化

事件的第四個特性是:“具象化”。事件會盡可能的把“案發現場”完整的記錄下來,因為它也不知道消費者會如何使用它,是以它會做到盡量的詳盡,包括:什麼時候發生?是由誰産生的事件?是什麼類型的事件?是誰發送的事件?事件的唯一性标志是什麼?事件的内容是什麼?等等。

再對比我們常見的消息,因為上下遊一般是确定的,常常為了性能和傳輸效率,則會做到盡可能的精簡,隻要滿足“計劃經濟”指定安排的消費者需求即可。

什麼是事件驅動架構?

Cloud Native

講完事件,我們再回過頭來,一起看看,什麼是事件驅動架構。為了友善了解,我們舉一個簡單的例子:我們都知道:交易系統在完成訂單交易之後,有很多系統都“需要”知道這個訂單資訊,比如:

  • 物流系統,需要知道這個訂單資訊,來安排發貨;
  • 積分系統,需要知道這個訂單資訊,來重新計算這個使用者的積分;
  • 營銷系統,需要知道這個訂單資訊,來計算當天的實時交易額。

這裡我們有三種方式來實作上遊交易系統和下遊物流、積分、營銷系統的內建。

上下遊內建

方式 1:主動調用

一種最簡單的實作方式是:交易系統依次調用每個系統,把訂單資訊發出去。比如下圖這種方式:

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

但我們都知道,這個設計,是非常糟糕。尤其當越來越多的系統加進來時,不僅開發成本高,而且萬一其中一個系統出現問題,處理不好,很容易影響其他系統的發送。

方式 2:消息異步解耦

一個很自然的解決方案是:我們将訂單資訊,發送到中間的一個消息 broker 服務。然後,物流系統、積分系統、營銷系統隻需要去訂閱 Broker 的這些交易訂單消息就可以了,非常簡單清晰。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

方式 3:事件驅動架構

那如果是在事件驅動架構中,應該怎麼做呢?交易系統,依舊會将交易訂單發送到我們中間的 Broker 服務,但是下遊服務不再需要主動訂閱 Broker 中的交易訂單,而往往是 Broker 推送給下遊系統。這個時候,大家可能既有疑問了,這個好像跟方式 2 消息異步解耦,沒有太大的差別吧?難道事件驅動架構,就是簡單的把 Pull 模式變成了 Push 模式?

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

這裡我們圍繞上遊和下遊,看看事件驅動架構帶來了什麼改變。

面向下遊

1、耦合的膨脹

這裡我們衍生一下,很多時候,下遊的營銷系統它不是隻依賴一個交易系統産生的訂單資料,比如:它可能同時需要淘寶的交易訂單、京東的交易訂單、拼多多的交易訂單,來實時計算一個目前時刻彙總值。這個時候,在“消息異步解偶” 的架構中,客戶的營銷系統需要做兩件事:

第一,訂閱三個 Broker 服務,來擷取淘寶、京東、拼多多的交易訂單資料;

第二,由于淘寶、京東、拼多多的交易訂單資料格式,是不同的,是以客戶的營銷系統,需要對三種資料格式進行适配,先轉換成營銷系統内部期望的資料格式,然後再處理。

而且,如果後面客戶又在抖音開店,客戶的營銷系統需要再适配一遍;如果某家的訂單資料格式發生變化,那客戶營銷額系統也必須關聯的進行更新。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

如果在事件驅動架構中,客戶的營銷系統,需要怎麼做呢?他什麼都不需要,隻要登高一聲大喊:“我需要什麼樣的訂單事件格式,我提供一個 API,其他系統就按這個訂單事件格式發給我就可以了”。EventBroker 會将上遊的事件轉換成客戶營銷系統需要的資料格式,發送給他的 API。不管接多少系統的交易訂單、不管外部系統怎麼變,反正我不變。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

2、耦合方向

這裡我們分析下這三種方式的耦合關系:我們要知道,耦合是有方向性的。

  • 方式 1-直接調用:是上遊 A 依賴下遊 B;(一旦下遊 B 發生改變,A 需要同步的改變)
  • 方式 2-消息異步解偶:是 B 依賴于 A;(一旦上遊 A 的資料格式,發生改變,B 需要同步的改變)
  • 方式 3-事件驅動:A 不依賴于 B,B 也不依賴于 A;(所有的耦合,都由中間的 Event Broker 來統一處理和維護)
Apache RocketMQ EventBridge:建構下一代事件驅動引擎

3、影響系統穩定的因子有哪些?

除了降低依賴,下遊系統在開發的時候,最關注的是什麼?對大部分業務場景來說,最重要的是:開發維護成本低、穩定又可靠。不過,在消息異步解偶架構中,大家有沒有發現,影響目前下遊這個系統發生變化的入口,是不是有兩個?(就是下面咖啡色的部分) 一個是 API;一個是消息訂閱。

一個系統,有兩個入口會引起發生變化,是一件非常麻煩的事。這意味着:我們在開發和維護這個系統的穩定性時,需要守護好兩個口子:無論是身份認證、審計、安全、流控、測試、維護等等,我們都要兩邊考慮。不僅成本高,而且很容易出問題。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

4、可測試性和可維護性

在事件驅動架構模式中,下遊系統隻需要提供一個 API 入口。

  • 對外:這個 API,既是用來接收上遊的事件,也可以用來和其他系統間的通訊;
  • 對内:這個 API 的設計,是圍繞下遊系統目前自己的領域模型去設計的,不需要去适配任何其他系統。

是以整個系統,會非常簡約。簡約的好處是:當我們需要變更系統時,隻需要保障我們提供的 API 可靠,可測試性和可維護性都大大提升。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

5、Serverless

事件驅動還有一個非常大的優勢是可以通過事件的方式,按量驅動 Serverless,去進行消費。還是在我們交易訂單這個場景下:

  • 有些小商家的的訂單量其實沒有那麼多,那單獨部署一個積分系統服務,7*24 小時一直跑着,是很浪費的一種行為。這個時候,如果通過事件驅動模式:當隻有交易訂單事件産生時,才去觸發下遊 Serverless 服務,按量計算付費,能夠極大的降低我們的成本;
  • 而對有些商家,交易訂單量非常大,尤其是遇到節日大促的時候,流量峰值會非常高,這個時候,如果通過事件驅動模式,按量觸發 Serverless 進行計算,能夠更好的提升系統的處理能力的峰值。
  • 另外,如果下遊系統會因為某些異常事件,影響系統穩定性。那通過事件驅動觸發 Serverless 的方式,天然的,就可以提供很好的隔離性,并實作快速恢複。

Serverless 已經逐漸成為雲原生時代一股勢不可擋的趨勢,而事件驅動和 Serverless 則是一對最好的兄弟組合。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

面向上遊

SaaS 內建

上面都是圍繞下遊展開,那對于上遊系統來講,事件驅動的意義在哪呢?我們想一下,對上遊系統來講,它最關心的是什麼?它關心的肯定不是系統的穩定性和解耦這些東西,不是說這些東西不重要,而是對上遊系統來講,發送到消息 Broker,和事件 Broker 沒什麼差別。那什麼對上遊系統來說是最重要的呢?這裡本質上是,上遊系統希望可以和更多的系統實作內建,來打造自己的生态位。

這個怎麼了解呢?我們舉一個例子:門禁打卡系統。

門禁打卡系統,賣給不同的公司,需要支援員工打卡的記錄資訊同步到不同公司的 ERP 系統中,這個時候,如果門禁打卡系統自己 One By One 去內建适配各個公司的 ERP 系統,成本是非常高的,幾乎不現實;如果不去內建,可能很多公司可能就不買你的了。

是以,對于上遊系統來說,能夠省心省力的與生态内的産品友善內建,是最重要的事情。而在事件驅動架構模式中,門禁打卡系統隻需要以事件的形式,把員工打卡事件記錄下來,交給事件中心,剩下的事情就不用操心了。事件中心會統一負責下遊生态的內建對接。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

另外,對于門禁打卡系統本身,它也需要知道新員工的入職事件,因為隻有這樣,在新員工打卡的時候,才能夠及時識别。如果通過事件驅動模式,門禁打卡系統就可以輕松的在 SaaS 生态中,從零開始,快速打造自己的生态位。

如何做一個優秀的事件驅動引擎

Cloud Native

前面講了這麼多,了解了什麼是事件以及什麼是事件驅動架構。也了解到事件驅動架構獨特的一些魅力:為什麼事件驅動架構,被越來越多的公司喜歡。

最後,我們講一下,如果要做一個優秀的事件驅動引擎,需要具備哪些能力?我們 RocketMQ EventBridge 怎麼做的?

需要什麼樣的能力?

第一,我們肯定得有一個事件标準。因為事件不是給自己看的,也不是給他看的,而是給所有人看的。事件沒有明确的消費者,所有都是潛在的消費者,我們得規範化事件的定義,讓所有人都能看得懂,一目了然;

第二,我們得有一個事件中心,事件中心裡有所有系統注冊上來的各種事件。這個有點類似市場經濟大賣場,玲琅滿目,裡面分類擺放了各種各樣的事件,所有人即使不買,也都可以進來瞧一瞧,看一看,有哪些事件,可能是我需要的,那就可以買回去;

第三,我們得有一個事件格式,用來描述事件的具體内容。這相當于市場經濟的一個買賣契約。生産者發送的事件格式是什麼,得确定下來,不能總是變;消費者以什麼格式接收事件也得确定下來,不然整個市場就亂套了;

第四,我們得給消費者一個,把投遞事件到目标端的能力,并且投遞前,可以對事件進行過濾和轉換,讓它可以适配目标端 API 接收參數的格式,我們把這個過程統一叫做訂閱規則。

第五,我們還得有一個存儲事件的地方,就是最中間的事件總線。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

如何描述事件

關于剛才提到的第一點事件标準,這個很重要。事件标準,就相當于不同系統之間交流的語言,如果語言都不通,互相交流肯定會出很多問題。我們推薦使用 CNCF 旗下的開源 CloudEvents 協定,目前已經很多公司廣泛內建,算是一個事實上的标準。CloudEvent 協定也很簡單,我們有一個簡單的例子, 詳細可以參考官網[1]:

{

  "specversion":"1.0",

  "type":"com.github.pull_request.opened",

  "source":"https://github.com/cloudevents",

  "subject":"123",

  "id":"A234-1234-1234",

  "time":"2018-04-05T17:31:00Z",

  "comexampleextension1":"value",

  "comexampleothervalue":5,

  "datacontenttype":"text/xml",

  "data":"<much wow=\"xml\"/>"

}           

事件中心

另外,我們必須得有一個事件中心。事件中心對于事件驅動架構來說,是非常重要的一個角色。他就像我們剛才說的市場經濟的大賣場,所有的事件,在這個大賣場裡,都有詳細的使用說明,大家都可以進來瞧一瞧,看一看,覺得合适,就訂閱買走。

至于事件中心如何管理,我們可以從API管理裡學習很多經驗:我們知道 API 包含注冊、Schema 描述、Sample、文檔、SDK、測試、監控。Event,其實也是一樣,它需要在事件中心被注冊,定義 Schema 描述、Sample、文檔、CodeBinding、測試、監控。

這樣消費者拿到這個事件的時候,才知道是什麼,怎麼用,用的放心。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

Schema

事件的 Schema,是用來描述事件中有哪些屬性、含義等等資訊。為什麼我們要引入Schema?一方面是,為了讓下遊能夠了解事件的格式,友善使用事件;另一方面,也是為了限制上遊發送事件的格式,發送和修改都必須保障相容,一旦契約簽訂,不能輕易修改。我們推薦使用 Json Schema 和 OpenAPI 3.0。

事件過濾和轉換

關于事件的過濾和轉換,RocketMQ 事件驅動引擎 提供了豐富的事件過濾和轉換方式。這些我就不具體一一展開了,詳細大家可以上圖描述。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

RocketMQEventBridge 技術架構

最後,我們 RocketMQ 圍繞事件驅動推出的産品,叫做 EventBridge,他的整個架構可以分為兩部分:上面是我們的控制面、下面是我們的資料面。

控制面:面向上遊,做好事件的管理。通過 EventSource,把上遊産生的事件,管理起來,讓大家找得到需要的事件,找到事件後,知道怎麼用;面向下遊,可以通過 EventRule,讓消費者,友善的把事件轉換成需要的格式,并推送給自己。

中間的 EventBus,是我們存儲事件的地方,底下使用的是我們 RocketMQ 自己的Broker;

資料面:是事件的通道,我們除了可以通過 API 發送事件到 EventBus 之外,還可以通過 Source Connector 主動拉事件到 EventBus。消費者建立 EventRule 之後,則可以通過 Sink Connector 将事件,推送到目标端;

除此之外,我們還會有:事件追蹤、事件回放、事件分析、事件歸檔等等。

Apache RocketMQ EventBridge:建構下一代事件驅動引擎

歡迎加入我們

Cloud Native

大家如果想進一步了解 EventBridge,可以掃描圖檔上的二維碼,也可以一起參與社群的建設。

RocketMQ EventBridge:

RocketMQ 學習社群體驗位址

RocketMQ 學習社群重磅上線!AI 互動,一秒了解 RocketMQ 功能源碼。RocketMQ 學習社群是國内首個基于 AIGC 提供的知識服務社群,旨在成為 RocketMQ 學習路上的“貼身小二”。

PS:RocketMQ 社群以 RocketMQ 5.0 資料為主要訓練内容,持續優化疊代中,回答内容均由人工智能模型生成,其準确性和完整性無法保證,且不代表 RocketMQ 學習社群的态度或觀點。

相關連結:

[1] 官網