新聞中心
微服務(wù)架構(gòu)相比單體架構(gòu)而言的優(yōu)點,可以列舉出很多:服務(wù)個體更小,更內(nèi)聚,業(yè)務(wù)職責(zé)更清晰,可復(fù)用性更強,可以獨立部署發(fā)布等等;從軟件開發(fā)的角度,靈活性和效率都會有很大的提升……

創(chuàng)新互聯(lián)建站專注于企業(yè)全網(wǎng)營銷推廣、網(wǎng)站重做改版、嶗山網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5高端網(wǎng)站建設(shè)、商城建設(shè)、集團公司官網(wǎng)建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為嶗山等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
然而,微服務(wù)架構(gòu)本質(zhì)上是分布式系統(tǒng)架構(gòu),各個服務(wù)需要配合協(xié)同來完成產(chǎn)品的需求,業(yè)務(wù)數(shù)據(jù)的分散使得服務(wù)之間需要通過集成來完成協(xié)同工作,那么問題來了,集成要采用什么方式?要以什么樣的原則進行?如何設(shè)計才能盡量保證不同服務(wù)之間數(shù)據(jù)的一致性?
混亂的實現(xiàn)
微服務(wù)架構(gòu)下推薦使用REST作為服務(wù)間同步通信的方式,對于非實時需求,可以基于事件來實現(xiàn)異步協(xié)作。這個原則非常簡單,也非常容易實現(xiàn),然而僅遵循這個原則卻很難讓我們沿著微服務(wù)的道路走下去。一些號稱微服務(wù)架構(gòu)的系統(tǒng),最初服務(wù)拆分并無太大問題,但隨著邏輯的不斷擴展,跨服務(wù)數(shù)據(jù)交換場景的增加,這個簡單的原則就很難指引日常的決策,甚至引發(fā)了一些新的問題,舉幾個例子:
服務(wù)循環(huán)依賴
在一些場景下服務(wù)A依賴服務(wù)B,會調(diào)用服務(wù)B的API,而在另外一些場景下,服務(wù)B也需要服務(wù)A的數(shù)據(jù),也會通過調(diào)用服務(wù)A的API來實現(xiàn)。單從實現(xiàn)層面來看,按需獲取數(shù)據(jù),實現(xiàn)很方便,可以完成業(yè)務(wù)要達成的效果;但從長遠來看,兩個服務(wù)的耦合越來越緊,未來新增需求的實現(xiàn)成本會越來越高,成為技術(shù)債
第三方系統(tǒng)集成實現(xiàn)到業(yè)務(wù)服務(wù)中
在一些業(yè)務(wù)場景下,當(dāng)前產(chǎn)品需要的業(yè)務(wù)數(shù)據(jù)需要從幾個第三方系統(tǒng)獲取并進行整合甚至經(jīng)過一些計算后才能使用,之前的一些項目在初期實現(xiàn)時,數(shù)據(jù)從第三方系統(tǒng)獲取后,經(jīng)過處理直接寫入業(yè)務(wù)數(shù)據(jù)庫,就把集成的代碼直接寫到業(yè)務(wù)服務(wù)中,看起來并沒有太大的問題,只要代碼上做好隔離就好了。但實際上,后期發(fā)生了一些棘手的問題讓我們不得不作出改變:
- 一些定時觸發(fā)的集成任務(wù),每次只會在一個服務(wù)實例上運行,在運行期間可能會有大量的數(shù)據(jù)讀取、計算、更新、插入等操作,會短時大量占用當(dāng)前服務(wù)實例的資源,嚴(yán)重的情況下當(dāng)前服務(wù)實例甚至無法正常對外提供服務(wù)
- 相似的集成以同樣的方式集成到業(yè)務(wù)服務(wù)中,比如不同品牌的產(chǎn)品庫存會從多個第三方系統(tǒng)獲取,業(yè)務(wù)服務(wù)變的臃腫
- 集成方的一些變化直接影響到業(yè)務(wù)服務(wù),比如API的升級,這種改變必須要重新升級部署業(yè)務(wù)服務(wù)才能完成
集成接口不冪等
無論在第三方系統(tǒng)集成和內(nèi)部服務(wù)的調(diào)用過程中,接口不冪等都會造成數(shù)據(jù)不一致的問題。最典型的場景是服務(wù)A調(diào)用服務(wù)B的接口更新或?qū)懭霐?shù)據(jù),服務(wù)B處理成功,但由于網(wǎng)絡(luò)原因,服務(wù)A沒有收到服務(wù)B的響應(yīng),服務(wù)A重試調(diào)用接口,此時,服務(wù)B由于接口不冪等返回異常的響應(yīng),導(dǎo)致業(yè)務(wù)流程無法繼續(xù)下去
理想是豐滿的,現(xiàn)實是骨感的,大多數(shù)的項目開始于滿懷激情的整潔架構(gòu)的夢想,而開發(fā)工作并不像想象的那么順利,伴隨著項目人員更替、交付壓力大、人員能力不足等等,架構(gòu)開始逐漸走向大家不期望的方向,技術(shù)債臺高筑,攻城獅們疲于奔命的追趕進度的同時,只能望債臺興嘆。
集成的原則
當(dāng)問題發(fā)生時,架構(gòu)師們都能第一時間站出來說這個設(shè)計太爛了,怎么能做成這樣;事后諸葛是我們積累經(jīng)驗的重要手段,從高筑的技術(shù)債臺,從疲于救火的線上問題,從接了新需求卻找不到合理方案……我們一直在總結(jié)經(jīng)驗,為了避免再次摔倒在同一個地方,有哪些架構(gòu)設(shè)計原則可以先行呢?
單向依賴
微服務(wù)拆分之初都定義了各個服務(wù)的上下游關(guān)系,我們可以定義上下游服務(wù)的依賴關(guān)系如下:
- 下游服務(wù)可以直接依賴上游服務(wù),下游服務(wù)可以通過上游服務(wù)提供的API同步對上游服務(wù)的數(shù)據(jù)進行讀寫
- 上游服務(wù)不依賴下游服務(wù),上游服務(wù)數(shù)據(jù)狀態(tài)變化如果會對下游服務(wù)產(chǎn)生影響,可以通過發(fā)布領(lǐng)域事件,由下游系統(tǒng)監(jiān)聽事件作出對應(yīng)的操作
服務(wù)間僅冗余引用信息
微服務(wù)的各個領(lǐng)域?qū)嶓w之間存在著各式各樣的關(guān)系,當(dāng)領(lǐng)域?qū)嶓wA依賴領(lǐng)域?qū)嶓wB的信息時,通常需要在領(lǐng)域?qū)嶓wA中保留一部分領(lǐng)域?qū)嶓wB的副本信息,那這份副本信息中該包含哪些信息呢?
舉個例子,領(lǐng)域?qū)嶓wA是訂單,領(lǐng)域?qū)嶓wB是客戶,客戶端每次查詢訂單信息時,都要求同時查出客戶的姓名、性別和手機號碼,將這3個關(guān)鍵信息冗余在訂單的服務(wù)中就可以輕松滿足需求了,一切聽起來是那么的美好。
然而,這3個關(guān)鍵信息如果是可以變化的,那么問題就來了,如果領(lǐng)域?qū)嶓wB中的信息更新了,領(lǐng)域?qū)嶓wA中的信息要不要更新,如果不更新會造成數(shù)據(jù)不一致,如果更新無端增加了復(fù)雜度,而很有可能因此而產(chǎn)生循環(huán)依賴。
因此,在無法確定數(shù)據(jù)變化的準(zhǔn)確情況時,在副本中只保留引用信息最保險,需要完整信息時可以通過引用查詢相關(guān)信息。
為第三方系統(tǒng)構(gòu)建外觀服務(wù)
面對第三方系統(tǒng)集成,在系統(tǒng)集成過程中要考慮的更周全,一般情況下,我們無法控制第三方系統(tǒng),一旦集成出現(xiàn)問題,需要溝通解決方案,排期開發(fā),聯(lián)調(diào)測試等等,修復(fù)周期很長。
另一個問題是第三方系統(tǒng)通常采用的技術(shù)?;蚣煞绞娇赡芎臀覀兊南到y(tǒng)完全不同。比如它可能是個非常老舊的系統(tǒng),提供的接口是基于XML的SOAP;再比如它可能無法提供API,只能通過導(dǎo)出文件到某個SFTP或發(fā)送郵件的方式進行集成……
為了讓第三方系統(tǒng)集成產(chǎn)生盡量小的影響,我們傾向于構(gòu)建外觀服務(wù)來隱藏第三方系統(tǒng)實現(xiàn)的細節(jié),通過外觀服務(wù)對第三方系統(tǒng)的功能進行包裝,提供和當(dāng)前系統(tǒng)更加一致的集成方式。我們可以把外觀服務(wù)和第三方系統(tǒng)看做是一個整體,那么第三方系統(tǒng)的集成對于當(dāng)前系統(tǒng)內(nèi)的服務(wù)來說,服務(wù)間的集成就可以和內(nèi)部服務(wù)一樣處理。而對于第三方系統(tǒng)集成相關(guān)的細節(jié)內(nèi)容被隔離在外觀服務(wù)中,第三方系統(tǒng)集成的變化,只需要修改外觀服務(wù)就可以了。
集成接口實現(xiàn)要考慮冪等性
這個原則非常簡單,但實現(xiàn)過程中非常容易被忽略,如果不在設(shè)計好的測試用例中,測試過程中也很難發(fā)現(xiàn)問題;多數(shù)情況下是到了線上,用戶使用的真實場景才會發(fā)現(xiàn)問題,這時已經(jīng)產(chǎn)生了業(yè)務(wù)影響。
因此在涉及集成的接口中,要特別關(guān)注,業(yè)務(wù)上是否要求接口的冪等性,接口不冪等的情況下業(yè)務(wù)是否能夠正常的流轉(zhuǎn)。
契約測試
服務(wù)提供的接口通常不只有一個消費者,不同消費者關(guān)心的信息往往可能也不一樣,隨著服務(wù)數(shù)量的增加,在沒有契約測試的情況下,很有可能發(fā)生因為一個需求修改了當(dāng)前服務(wù)接口的實現(xiàn),而影響其他已有功能。而往往這個問題直到全面回歸的時候才能完全發(fā)現(xiàn),甚至可能發(fā)生因改動范圍很小,回歸不夠,在上線前也難以發(fā)現(xiàn)。
契約測試可以很好的解決這個問題,一方面測試前置,盡早提供反饋,另一方面也起到了架構(gòu)守護的作用。
小結(jié)
系統(tǒng)集成是分布式系統(tǒng)中一定會談及的問題,而且是個大問題,因為它直接影響到當(dāng)前系統(tǒng)的架構(gòu),一個微不足道的改動很可能就破壞了整個系統(tǒng)架構(gòu)的原則,久而久之原則便形同虛設(shè)。
微服務(wù)架構(gòu)也不例外,在缺少架構(gòu)約束的情況下,只圖一時之快的實現(xiàn)往往會葬送了微服務(wù)的優(yōu)勢,一個個微小的不合理改動會逐漸將整個架構(gòu)大廈摧毀,所謂千里之堤,潰于蟻穴就是這個道理。
因此,在微服務(wù)架構(gòu)設(shè)計之初,我們就要在團隊內(nèi)建立一些原則,明確系統(tǒng)間集成需要遵守的一些規(guī)范,并且在實踐過程中定期review,必要時可以采用一些架構(gòu)守護的輔助工具,來保護架構(gòu)的健康度。
本文題目:微服務(wù)架構(gòu)下的系統(tǒng)集成
本文URL:http://m.fisionsoft.com.cn/article/djhcsho.html


咨詢
建站咨詢
