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