天天看點

事件驅動架構(翻譯)

事件驅動的架構模式時一個非常流行的分布式異步架構模式,通常用來生成高擴充性的應用。它的适應性非常強,可以用在小應用也可以用在大的複雜的應用上。事件驅動的架構是由高度解耦、單目的的事件處理單元組成,這些單元異步地接受和處理事件。

時間驅動架構模式主要由兩種拓撲結構組成,中繼器與代理。如果你需要把一個事件中各個步驟通過中央中繼器組合起來,那麼就使用中繼器拓撲結構。當你不想有中央中繼器,而是将各個步驟串起來,就使用代理拓撲結構。因為不同拓撲結構的特性和實作差別挺大,是以有必要搞清楚這兩者來選擇最适合應用的結構。

中繼器拓撲

如果事件有許多步驟而且需要有效的組合在一起來處理事件,中繼器拓撲會很實用。舉例來說,一個單一的事件,完成證券交易,這個事件需要你首先驗證這個交易,然後檢查交易的合規性,再講交易委托給代理,計算傭金,最終通過代理完成交易。是以這些步驟都需要有效的組合,來決定步驟的順序,以及哪些步驟應該串行,哪些該并行。

中繼器拓撲主要有四種不同的架構組成部分:事件隊列,事件中繼器,事件通道,事件處理器。事件流從一個用戶端發送事件到事件隊列開始,事件隊列将事件傳給中繼器。中繼器接受最初事件然後将事件分解成各個步驟,發送到不痛的事件通道來執行每一步。事件處理器,會監聽事件通道,從事件中繼器接受事件并執行具體的業務邏輯。圖2-1說明了事件驅動的中繼器拓撲結構。

事件驅動架構(翻譯)

在事件驅動架構中,通常有十幾到幾百個事件隊列。事件隊列的實作并沒有限制,可以是一個消息隊列,一個wed服務端點,或者是他們的組合。

在這種模式下,有兩類事件:初始事件和待處理事件。初始事件是中繼器接受的原始事件,而待處理事件是由中繼器生成并由事件處理單元接收。

事件中繼器負責組織初始事件包含的步驟。對每一個步驟,中繼器會發送一個特定的待處理事件到事件通道,然後待處理事件會被事件處理器接收并處理。需要重點關注的是,中繼器并不直接執行處理初始事件的業務邏輯,而是将初始事件分為幾個步驟。

事件通道是中繼器用來給事件處理器異步發送待處理事件的,這些待處理事件是初始事件經過中繼器生成的。事件通道可以是消息隊列或者消息主題,待處理事件被多個事件處理器處理(每個處理器根據接收的事件處理不同的任務)。

事件處理器包含對事件處理的業務邏輯。事件處理器是獨立的、互不依賴的、高度解耦的結構,處理應用中某個具體的任務。盡管時間處理器的粒度可能從很精細(根據書序計算商業稅)到很粗糙(處理一項保險申購),還是要注意大體上,每個事件處理器都應該執行不同的任務而且不應該依賴其他的處理器來完成它自身的任務。

事件中繼器可以通過各種各樣的方法來實作。作為一個架構師,我們應該了解每一種實作來確定我們選擇的方案是最适應應用場景的。

最簡單常見的事件中繼器實作方案是開元的內建蜀繡,比如Spring Integration, Apache Camel, 或Mule ESB。這些開元內建樞紐的事件流通常是用Java或DSL實作的。對于更複雜的中繼器群組合方法,可以用BPEL(business process execution language)耦合一個BPEL引擎比如開元的Apache ODE。BPES是一個像XML一樣的标準語言,它描述可以描述處理初始事件的資料和步驟。對非常大型的應用來說,如果包含非常複雜的組合(保羅需要人為幹預的步驟),可以用一個BPM比如jBPM來實作。

了解需求畢竟找到最适合場景的中繼器實作,是中繼器拓撲結構最重要的事情。使用一個開源的基礎樞紐來進行非常複雜的業務處理管理是失敗的,就想使用BPM來處理非常簡單的邏輯,一樣也是失敗的。

為了說明中繼器邏輯是如何工作的,假設你已經被保險公司确認投保,然後你決定執行。在這個例子中,初始事件可以稱作“重定位事件”。圖2-2表明了中繼器怎麼處理一個重定位事件。對每個初始事件步驟,事件中繼器會建立一個待處理事件(比如修改位址,重新計算報價等),将待處理事件發送給事件通道并等待事件通道被相應的事件處理器處理。這個處理會一直持續知道所有的初始事件被處理完畢。重新計算報價和更新理賠的步驟,是可以同時異步執行的。

事件驅動架構(翻譯)

代理人拓撲

代理人拓撲和中繼器拓撲最大的差別是代理人沒有中央事件中繼器;小溪流像鍊條一樣分布到事件處理器中,這過程由一個輕量級的消息代理(如ActiveMQ,HornetQ等)完成。當你需要一個相對簡單的事件處理過程而且你不需要中央組成器的時候,這種拓撲結構就會非常有用。

代理人拓撲也有兩類主要的成分:代理人和事件處理器。代理人元件可以是集中式或聯邦式的,而且包含所有事件流中用到的的事件通道。這些事件通道可以是消息隊列,消息主體或者兩者結合。

圖2-3就是代理人拓撲結構。可以從圖表中看出,沒有中央事件中繼器元件控制群組合初始事件;二是每個事件處理器元件負責處理一個事件并且釋出一個新的事件來說明它剛才執行的動作。舉例來說,一個事件處理器比如平衡一個證券投資組合,可能會接受一個叫做股票拆分的初始事件。基于這個初始事件,事件處理器會做一些投資組合調整,然後釋出一個新的事件“調整投資組合”給代理人,這個事件會被另外一個不同的事件處理器接收。注意到會有一個事件被發出來後沒有被另一個事件處理器接收的情況發生。這通常發生在你給應用更新或者提供一些未來的功能和拓展的時候。

事件驅動架構(翻譯)

為了說明代理人拓撲的工作方式,我們使用和中繼器拓撲一樣的例子(一個确認投保的人搬家)來說。因為代理人拓撲沒有一個中央事件中繼器來接收初始事件,消費者處理元件直接接收這個事件,改變消費者的位址(如 位址變更事件)。在這個例子中,有兩個事件處理器對位址變更事件感興趣:報價處理和理賠處理。報價處理器根據位址變更重新計算新的汽車保險賠率,并釋出一個事件告訴其他處理器它所做的事情。理賠處理元件,另一方面,接收同樣的位址變更事件,但是它會更新一個沒有理賠的保險并釋出一個新的事件“更新理賠”到系統中去。這些新的事件會被其他事件處理元件接收,而且這個鍊式的系統會一直進行直到沒有和初始事件有關的事件産生。

事件驅動架構(翻譯)

從圖2-4中可以看到,代理人拓撲所有都是有關業務邏輯處理的整個過程。最好的了解方式就是把它想象成一個接力賽。在接力賽中,運動員拿着一個接力棒然後跑一段固定的距離,然後将接力棒交給下一個運動員,依次進行知道最後一個運動員沖過終點。在接力賽中,一旦運動員交接完接力棒,他就和接力賽無關了。這對代理人拓撲也是适用的:一旦一個事件處理器交接了事件,它就不會再參與到這個事件的處理過程中。

思考

事件驅動架構模式實作起來相對來說比較複雜,根本上是因為它的異步分布式本質。當我們實作這個模式時,一定要處理各種各樣的分布式架構的問題,比如遠端處理能力,相應的缺乏,以及代理或中繼器失敗後的重連邏輯。

一個需要考慮的點是當選擇這種模式時,需要考慮單個業務處理之間的原子性。因為事件處理器是高度解耦和分布的是以很難維持一個工作的食物單元。出于這個原因,在使用這種模式設計應用時,一定要持續思考哪些事件可以或不可以獨立執行,以及根據事件來設定事件處理器的粒度。如果需要将單一工作拆分到多個事件處理器中,即需要強行把一個能單獨處理的事物拆分到多個事件處理器,那麼可能不太适合這種模式。

也許事件驅動最難的部分是事件處理器元件資料結構的創造、維護和管理。每個事件通常都有一個特定的結構(如 傳給處理器的資料值和資料格式)。當使用這種模式時,標明一個标準的資料格式非常重要,然後從一開始就建立資料結構的控制。

模式分析

全局靈活性

評分:高

分析:全局靈活性是對持續變化的環境做出快速響應的能力。由于事件驅動元件都是單一目的而且和其他處理器是完全解耦的,是以改變也會隔離在一個或少數處理器中是以使得它能夠快速的對改變做出應對且不影響其他元件。

部署容易程度

評分:高

分析:總體來說這種模式相對來說是比較容易部署的,因為各個事件處理器天然是解耦的。代理人拓撲比中繼器拓撲更容易部署,主要是因為中繼器拓撲有中央中繼器,中繼器和事件處理器都和中央中繼器耦合,是以事件處理器的改變可能也會引起事件中繼器的改變,兩者都需要重新部署。

可測試性

評分:低

分析:盡管獨立單元測試總體來說并不難,也不需要一些特定的用戶端或工具來獲得測試結果。但是由于這種模式的異步天性,測試還是一件複雜的事情。

性能

評分:高

分析:盡管由于事件驅動架構包含一個消息隊列結構,會造成這種架構性能的下降,但是通常,由于異步特性,這種模式還是具有非常高的性能。換句話說異步和解耦分布式帶來的好處比消息隊列帶來的壞處要大。

可擴充性

評分:高

分析:擴充性是這種架構模式的天性,因為整個架構都是解耦的,分布式的。每個事件處理器都可以獨立的擴充。

開發容易程度

評分:低

分析:由于異步特性,這種模式開發起來可能不那麼容易。

繼續閱讀