您好,登錄后才能下訂單哦!
如果第二次看到我的文章,歡迎文末掃碼訂閱我個人的公眾號(跨界架構師)喲~
本文長度為3633字,建議閱讀10分鐘。
堅持原創,每一篇都是用心之作~
如果我們的開發工作真的就如搭積木一般就好了,輪廓分明,個個分開,壞了哪塊積木換掉哪塊就好了。
但是,實際我們的工作中所面臨的可能只有一塊積木,而且還是一大塊,要換得一起換,要修得一起修。
Z哥在之前《分布式系統關注點(13)——「高內聚低耦合」詳解》中提到的分層架構它可以讓我們有意識的去做一些切分,但是換和修的難度還是根據切分的粒度大小來決定的。
有更好的方式嗎?這是顯然的。
我們來換一個思維看待這個問題。
不管是平時的系統升級也好、修復bug也好、擴容也好,其實就是一場“手術”。通過這場“手術”來解決當前面臨的一些問題。
那么分層架構好比只是將一個人的手、腳、嘴、鼻等分的清清楚楚,但是整體還是緊密的耦合在一起。
怎么耦合的呢?我們人是靠“血液”的流動連接起來的。這就好比在分布式系統中通過rpc框架連接起不同的節點一樣。
但是軟件與人不同,有2種不同的連接方式,除了「同步」的方式之外還有「異步」的方式。因為有些時候你不需要知道其他系統的執行結果,只要確保自己將其需要的數據傳遞給它了即可。
恰巧有一種架構是這種模式的典型——事件驅動架構(簡稱EDA,Event Driven Architecture)。
平時常見的MQ、本地消息表等運用于數據傳遞的中轉環節,就是事件驅動架構的思想體現。
事件驅動架構又細分為兩種典型的實現方式,與Z哥之前在《分布式系統關注點(3)——「共識」的兄弟「事務」》中提到的Saga模式的2種實現方式類似,一種是中心化的、一種是去中心化的。
下面Z哥來舉個例子,讓你看起來更容易理解一些。(例子僅為了闡述是怎么工作的,真正的實施中還需要考慮如何保證數據一致性等問題,這部分可以參考之前發表的系列文章,文末帶傳送門)
傳統的電商場景中,用戶從購物車中點擊“提交”按鈕后,至少需要做這幾件事:生成一筆訂單、生成一筆支付記錄、給訂單匹配發貨的快遞公司。
在這個場景下,中心化和去中心化有什么不同呢?
這種模式擁有一個“上帝”。
但是“上帝”不會處理也不知道任何業務邏輯,它只編排事件。
除了中心化之外,它還有什么特點呢?Z哥給它的定義是“3+2結構”。
這種模式中存在3種類型的主體:事件生產者、“上帝”(調停者)、事件處理者。然后中間夾著兩層隊列,以此結構就能解耦。
就像這樣:事件生產者 --> 隊列 --> “上帝”(調停者) --> 隊列 --> 事件處理者。
那么回上面的這個例子中,事件生產者CartService發出了一個“訂單創建”事件,通過隊列傳遞給調停者。然后調停者根據事先制定好的編排規則對事件進行相應的轉換,也通過隊列做二次分發,傳遞給事件處理者。
可能你會問,這些好理解。但是,我之前也經常看到什么編排編排的,到底編排該怎么做呢?
其實編排主要做兩件事:「事件轉換」和「事件發送」(對應「服務編排」類框架的「調用」)。
「事件轉換」實質就是給將要發送的事件對象的參數進行賦值。賦值的數據來源于哪呢?
除了事件產生的源頭帶入的參數,還有持續累積的「上下文」,就如下圖中這樣的一個共享存儲空間。
可能你又會問,我怎么將多個事件處理者之間組合成一個上下文呢?
通過一個全局唯一的標識即可,每次向“上帝”丟事件的時候把這個全局唯一標識帶過去。
題外話:一般來說,還會在一個全局唯一標識之下帶一個內部唯一的「子流水號」,為了配合做接下去要講到的「事件發送」。
一是為了后續排查問題的時候清晰的知道這次調用產生的異常是從哪個上游系統來的。
二是為了便于觀測整個調用的邏輯是否符合編排時的預期。
怎么做呢?通過一個x.x.x.x格式的序號。比如,串行就是1,2,3。分支和并行就是2.1,2.2。分支+串行的結合就是1,2,2.1,2.2,3。
「事件發送」實質就是負責事件流轉的邏輯控制,然后發往「事件處理者」去處理。它決定了是按順序還是分支進行?是串行還是并行?
到這就不再展開了,要不然就跑題了,我們下次再細聊這部分內容。
再強調一下,「事件轉換」和「事件發送」是你在實現“上帝”(調停者)功能的時候需要滿足的最基本的兩個功能哦。
中心化最大的優勢是讓流程更加的“可見”了,同時也更容易去做一些監控類的東西,系統規模越大,這個優勢產生的效果越明顯。
但是一個最基本的“上帝”(調停者)實現起來還需要考慮數據一致性問題,所以,會大大增加它的實現復雜度。
因此,如果你面對的場景,業務沒有特別龐大,并且是比較穩定的,或許用去中心化的方式也是不錯的選擇。
這個模式由于沒有了“上帝”,因此每個事件處理者需要知道自己的下一個事件處理器是什么?需要哪些參數?以及隊列是哪個之類的東西。
但是整體結構會變得簡單很多,從“3+2結構”變成了“2+1結構”。
結構簡化背后的復雜度都跑到事件處理者開發人員編寫的業務代碼中去了。因為他需要自己去負責「事件轉換」和「事件發送」這兩個事情。
嗯,改造成事件驅動架構之后,通過「隊列」的解耦和異步的事件流轉,系統的運轉的確會更順暢。
但是有時候你可能想進行更細粒度的控制,因為一般情況下,一個service中會處理很多業務環節,不太會只存在一個對外接口、一條業務邏輯。
在這樣的情況下,很多時候你可能需要修改的地方僅僅是其中的一個接口。能不能只修改其中的一部分代碼并且進行「熱更新」呢?
微內核架構(插件架構)就適合來解決這個問題。
顧名思義,微內核架構的關鍵是內核。所以需要先找到并明確內核是什么?然后將其它部分都視作“可拆卸”的部件。
好比我們一個人,大腦就是內核,其它的什么都可以換,換完之后你還是你,但是大腦換了就不是你了。
微內核架構整體上由兩部分組成:核心系統和插件模塊。
核心系統內又包含了微內核、插件模塊,以及內置的一些同樣以插件形式提供的默認功能。
其中,微內核主要負責插件的生命周期管理和控制插件模塊。
插件模塊則負責插件的加載、替換和卸載。
外部的插件如果要能夠接入進來并順利運行,前提先要有一個滿足標準接口規范的實現。
一個插件的標準接口至少會有這樣的2個方法需要具體的插件來實現:
public interface IPlugin{ /// <summary> /// 初始化配置 /// </summary> void InitializeConfig(Dictionary<string,string> configs); /// <summary> /// 運行 /// </summary> void Run(); ... }
最后,插件之間彼此獨立,但核心系統知道哪里可以找到它們以及如何運行它們。
知道了這兩種具有“彈性”的架構模式,你該如何判斷什么情況下需要搬出來用呢?
Z哥帶你來分析一下每一種架構的優缺點,就能發現它適用的場景。
它的優點是:
通過「隊列」進行解耦,使得面對快速變化的需求可以即時上線,而不影響上游系統。
由于「事件」是一個獨立存在的“標準化”溝通載體,可以利用這個特點銜接各種跨平臺、多語言的程序。如果再進行額外的持久化,還能便于后續的問題排查。同時也可以對「事件」進行反復的「重放」,對處理者的吞吐量進行更真實的壓力測試。
更“動態”、容錯性好。可以很容易,低成本地集成、再集成、再配置新的和已經存在的事件處理者,也可以很容易的移除事件處理者。輕松的做擴容和縮容。
在“上帝”模式下,對業務能有一個“可見”的掌控,更容易發現流程不合理或者被忽略的問題。同時能標準化一些技術細節,如「數據一致性」的實現方式等。
它的缺點是:
面對不穩定的網絡問題、各種異常,想要處理好這些以確保一致性,需要比同步調用花費很大的精力和成本。
無法像同步調用一般,操作成功后即代表可以看到最新的數據,需要容忍延遲或者對延遲做一些用戶體驗上的額外處理。
那么,它所適用的場景就是:
對實時性要求不高的場景。
系統中存在大量的跨平臺、多語言的異構環境。
以盡可能提高程序復用度為目的的場景。
業務靈活多變的場景。
需要經常擴容縮容的場景。
它的優點是:
為遞進設計和增量開發提供了方便。可以先實現一個穩固的核心系統,然后逐漸地增加功能和特性。
和事件驅動架構一樣,也可避免單一組件失效,而造成整個系統崩潰,容錯性好。內核只需要重新啟動這個組件,不致于影響其他功能。
它的缺點是:
由于主要的微內核很小,所以無法對整體進行優化。每個插件都各自管各自的,甚至可能是由不同團隊負責維護。
一般來說,為了避免在單個應用程序中的復雜度爆炸,很少會啟用插件嵌套插件的模式,所以插件中的代碼復用度會差一些。
那么,它所適用的場景就是:
可以嵌入或者作為其它架構模式的一部分。例如事件驅動架構中,“上帝”的「事件轉換」就可以使用微內核架構實現。
業務邏輯雖然不同,但是運行邏輯相同的場景。比如,定期任務和作業調度類應用。
具有清晰的增量開發預期的場景。
好了,我們總結一下。
這次呢,Z哥向你介紹了「事件驅動架構」的兩種實現模式和實現思路,以及「微內核架構」的實現思路。
并且奉上了對這兩種架構模式的優缺點與適用場景分析的最佳實踐。
希望對你有所啟發。
相關文章:
分布式系統關注點(1)——初識數據一致性
分布式系統關注點(2)——通過“共識”達成數據一致性
分布式系統關注點(3)——「共識」的兄弟「事務」
作者:Zachary
出處:https://www.cnblogs.com/Zachary-Fan/p/flexiblearchitecture.html
如果你喜歡這篇文章,可以點一下左下角的「大拇指」。
這樣可以給我一點反饋。: )
謝謝你的舉手之勞。
?關于作者:張帆(Zachary,個人微信號:Zachary-ZF)。堅持用心打磨每一篇高質量原創。歡迎掃描下方的二維碼~。
定期發表原創內容:架構設計丨分布式系統丨產品丨運營丨一些思考。
如果你是初級程序員,想提升但不知道如何下手。又或者做程序員多年,陷入了一些瓶頸想拓寬一下視野。歡迎關注我的公眾號「跨界架構師」,回復「技術」,送你一份我長期收集和整理的思維導圖。
如果你是運營,面對不斷變化的市場束手無策。又或者想了解主流的運營策略,以豐富自己的“倉庫”。歡迎關注我的公眾號「跨界架構師」,回復「運營」,送你一份我長期收集和整理的思維導圖。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。