忻州内厩机械设备有限公司

熱門系統(tǒng)產(chǎn)品
電商交易類產(chǎn)品
渠道/經(jīng)銷商產(chǎn)品
AI人工智能產(chǎn)品
業(yè)務協(xié)同系統(tǒng)產(chǎn)品
其他產(chǎn)品與服務
沒有你合適的?
我要定制 >

微服務架構設計實踐總結和思考

發(fā)布時間: 2021-02-04 文章分類: 技術干貨
閱讀量: 0

微服務系統(tǒng)架構

對于SOA和微服務,我前面很多文章都進行了詳細的闡述,今天這篇文章重點還是放在一些架構設計和實踐的一些關鍵點思考上面。

微服務架構核心

再次強調(diào),微服務架構核心是傳統(tǒng)單體應用大拆小,同時拆分為小的微服務后相互之間以輕量的API接口進行通信。而這個拆分本身又分了多個方面。

開發(fā)團隊的拆分

代碼層的拆分,可獨立構建打包。

數(shù)據(jù)庫的拆分

在拆分后為了更加敏捷開發(fā)和集成,引入了DevOps和容器云技術。同時考慮和SOA,中臺思想的融合,考慮到API接口的復用性,進一步對單個微服務也進行了前后端分離開發(fā)。

從單微服務的概念來說,微服務不是指具體的Http API接口服務,而是指拆分后的微服務模塊,因此微服務可以理解為:拆分后DB+微服務模塊+API接口提供。

微服務架構思想符合當前復雜應用系統(tǒng)分而治之的思想,這個和微服務出來前的組件化開發(fā)思路是一致的,只是微服務思想出來后對于拆分的微服務更加高度解耦和獨立自治。

系統(tǒng)復雜性本身也分為了功能和非功能兩個層面。

比如一個傳統(tǒng)的大業(yè)務系統(tǒng),類似ERP,合同管理等,業(yè)務系統(tǒng)足夠復雜,需要考慮進行分為治之方便后期管理和擴展。其次是非功能性需求導致的復雜性,比如一個業(yè)務系統(tǒng)功能并不多,但是文件存儲和獲取量巨大,那么文件服務就需要單獨拆分為微服務。

在很早以前我就強調(diào)過,微服務拆分后雖然降低了單個微服務開發(fā)實現(xiàn)的難度,但是增加了集成的難度,拆分的越細集成越復雜。因此如果本身不具備上面談到的復雜性需求,一個業(yè)務系統(tǒng)沒有必要進行微服務架構拆分和改造。

按劃分后的子域拆分數(shù)據(jù)庫

在我們實際的項目中,一個原來的單體業(yè)務系統(tǒng),在進行微服務化后,實際拆分為了20個微服務模塊,那么按標準的微服務原則,應該后端也拆分為20個數(shù)據(jù)庫實例。但是這樣會導致巨大的集成復雜度和大量分布式事務處理問題。

微服務架構設計實踐總結和思考

顯然,在這種場景下我們引入業(yè)務域的概念,即應該按業(yè)務域或子域來拆分數(shù)據(jù)庫,可以多個微服務共享一個數(shù)據(jù)庫。在多個微服務共享一個數(shù)據(jù)庫實例的時候,微服務本身沒有做到完全解耦,但是也可以實現(xiàn)代碼層解耦。

比如某一個需求變更導致微服務A進行了變更,數(shù)據(jù)庫沒有變化,那么我們只需要持續(xù)集成和發(fā)布微服務A模塊即可。

同時在劃分業(yè)務域后也更加方便進行團隊的劃分,即開發(fā)團隊也按照業(yè)務域進行劃分,而不是一個開發(fā)團隊只負責一個微服務模塊。

微服務和微服務API接口

注意微服務和微服務模塊暴露的API接口是兩個概念,這本身也是進行微服務邊界劃分和微服務管控的兩種顆粒度。

在主流的微服務開發(fā)框架實現(xiàn)中,類似SpringCLoud的實現(xiàn),對于Eureka,CloudGateway網(wǎng)關等實際都是到微服務這個粒度,也就是服務注冊和接入的是微服務模塊,而不是一個個獨立的API接口服務。一旦微服務注冊接入后,消費端通過注冊中心查找到可用的微服務后,那么該微服務通過聲明式方式暴露的所有API接口都處于可用狀態(tài)。

在微服務架構開發(fā)下,團隊實際應該有更加明確的邊界,更加粗粒度的接口暴露和交互,而不是簡單的團隊A在發(fā)現(xiàn)團隊B的微服務后,里面所有的API接口都可以隨意調(diào)用,這樣反而是導致了更多的內(nèi)部規(guī)則外協(xié),也加強了兩個微服務模塊之間的耦合性。

簡單來說,兩個微服務之間,不是通過API接口調(diào)用就真正解耦了,而是兩個微服務之間僅僅只有少量粗粒度的API接口交付才算真正解耦。

當前實際我們發(fā)現(xiàn)的一個關鍵問題就是微服務也拆分了,開發(fā)團隊也拆分了,但是多個微服務之間仍然是大量接口隨意調(diào)用,這本質仍然是一種緊耦合的架構而難以擴展。

微服務架構設計實踐總結和思考

如上圖,微服務A,D,E分別由不同的開發(fā)團隊開發(fā),那么他們之間的邊界應該控制到具體的API接口粒度,而不是微服務粒度。比如對于微服務E只能消費微服務A暴露的第2個接口,而不能消費接口1。如果單純的采用微服務注冊中心方式,實際我們很難真正控制到API接口的粒度?;蛘哒f需要我們自己寫相應的代碼來做細粒度的安全控制。

面向API接口設計

微服務架構設計實踐總結和思考

這個是我在前面一直強調(diào)的觀點,即大型項目或傳統(tǒng)的大型單體應用在進行微服務化的時候,一定是架構設計先行。架構設計的關鍵工作就是:

微服務模塊拆分,包括數(shù)據(jù)庫拆分

微服務模塊暴露的API接口識別定義

當做完這兩件事情后,單個微服務才能夠真正傳遞給不同的開發(fā)團隊或小組進行獨立的設計開發(fā)工作。同時在微服務開發(fā)過程中,需要面向API接口而設計開發(fā),要優(yōu)先基于前面定義的接口契約來實現(xiàn)需要暴露給外部其他微服務使用的接口,其次再考慮內(nèi)部功能邏輯實現(xiàn)。

接口先行的好處就是大家遵循同樣的一套接口契約,可以并行開始相關的設計和開發(fā)工作,只要接口契約相同,那么后續(xù)在多個微服務間集成的時候就應該沒有問題。

API接口的治理管控需要提升到相對重要的一個位置。

在微服務架構實踐中經(jīng)??吹降那闆r就是前期架構設計不充分,相關的邊界劃分不明確,接口定義不明確,導致后期微服務在設計開發(fā)過程中持續(xù)大量的交互,同時隨意的增加和定義新的API接口,這種場景下必然帶來后續(xù)接口交互和管控治理的混亂。

比如后續(xù)在進行微服務變更的時候,我們很難快速的分析出該微服務或API接口變化究竟會影響到哪些其它的微服務模塊,微服務和API間的交互依賴關系我們也完全不清楚。

這也是我在很早就強調(diào)的一個觀點,不要期望通過后期的APM或服務鏈監(jiān)控來解決微服務本身架構設計階段的不足,而是應該在前期就按自頂向下思路設計好。

構建獨立的領域組合微服務

在SOA分層架構里面可以看到,最底層是原子服務,在原子服務上面有組合服務,在組合服務上面還有流程服務。也就是說服務本身也是分層的,雖然越往上走,類似到了組合服務實際的復用度會降低,但是復用效率本身卻是加快。

在微服務架構實踐里面,原有的單體應用已經(jīng)拆分為了不同的微服務,每個微服務都可以提供獨立的API接口服務能力給前端使用。

但是當前端需要的是多個微服務的組合能力的時候,這個能力究竟放在哪里?比如前面我們舉過一個例子,對于訂單提交這個操作,實際需要調(diào)用后端訂單中心,預算中心,庫存中心多個微服務接口才能夠完成。

在傳統(tǒng)方式下這個能力實際是在前端模塊完成組合和協(xié)同,但是你會發(fā)現(xiàn)你開發(fā)的應用既有傳統(tǒng)的BS端應用,也有APP應用,那么這個組合顯然就需要在兩個地方重復實現(xiàn)。同時這種組合規(guī)則本身也暴露到了前端不合理。

微服務架構設計實踐總結和思考

領域組合微服務實際上是一類比較特殊的微服務,即這類微服務本身完成多個微服務API接口的組合編排,完成分布式事務管理和協(xié)調(diào),完成組合業(yè)務規(guī)則的實現(xiàn)和處理等。

這類微服務本身沒有自己獨立的Owner數(shù)據(jù)庫,也就是這類微服務不直接進行數(shù)據(jù)庫DB層的數(shù)據(jù)訪問和交互,而是直接復用已有的接口服務能力進行組合和組裝。

在DDD領域驅動設計的架構分層里面,在領域層上有一個獨立的應用層,這個應用層即和這類談到的領域組合微服務對應。而下層的領域層則由多個微服務提供粗粒度的API接口服務能力。

微服務網(wǎng)關和API網(wǎng)關

在前面我曾經(jīng)專門寫過微服務網(wǎng)關。API網(wǎng)關一般具備獨立的服務注冊接入,負載均衡和路由能力,而微服務網(wǎng)關一般則是通過和服務注冊中心的集成來實現(xiàn)服務注冊發(fā)現(xiàn),負載均衡和路由。

簡單來說如果當前微服務A模塊有100個接口服務。

在有服務注冊發(fā)現(xiàn)中心的情況下,微服務A模塊部署后會被注冊中心自動發(fā)現(xiàn),并加入到可用集群列表中。因此在微服務網(wǎng)關和注冊中心集成后,所有的接口服務也自動的注冊和接入到了微服務網(wǎng)關中。

當用戶訪問網(wǎng)關提供的服務地址時候整體過程如下圖:

微服務架構設計實踐總結和思考

在這種場景下可以看到實際并不用一個個的API接口在網(wǎng)關上面注冊。但是也無法控制一個微服務哪些具體的接口要接入網(wǎng)關,哪些不接入。同時這里的微服務網(wǎng)關實際上本身也是整體微服務架構體系里面的一個微服務模塊,充當了服務消費方的角色。

也就是說APP應用無法受整體微服務框架管轄,那么對應的依賴包,代理SDK等無法下放到外部應用中,那么這部分內(nèi)容實際是轉移到微服務網(wǎng)關上來幫助外部APP應用完成。而對于相對獨立的API網(wǎng)關來說,整體的注冊和接入過程是在API網(wǎng)關上面獨立完成的,而是是控制到API接口服務粒度進行。

當然,你也可以不采用微服務網(wǎng)關,直接采用類似Nginx來進行代理和路由轉發(fā),但是這個時候需要手工進行微服務節(jié)點的配置和心跳檢測實現(xiàn)等。

一個完整的微服務架構你可以看到。比如有三個獨立開發(fā)團隊進行自己的微服務開發(fā),每個團隊本身又采用前后端分離的開發(fā)模式。那么這個時候實際上每個團隊都可以啟用自己的注冊中心和微服務網(wǎng)關,但是多個團隊之間的接口協(xié)同則必須控制到API接口這個粒度,即多個團隊之間的接口協(xié)同采用API網(wǎng)關進行。

這個時候的API網(wǎng)關不屬于單個開發(fā)團隊管理,而屬于整個平臺層的集成能力。

共性基礎JAR包依賴

微服務架構設計實踐總結和思考

在微服務架構拆分后,各個微服務仍然會使用或依賴一些共性基礎組件,這些組件本身是獨立工程項目,可以獨立編譯構建。

同時各個微服務本身以黑盒Jar包的方式對基礎組件包進行依賴。

這類似于在各個微服務里面本身有一個基礎的內(nèi)置SDK包,這個SDK包實現(xiàn)了一些基礎共性可復用的方法,或者對一些技術能力進行了統(tǒng)一封裝。

在這種場景下如果微服務B對Common包提出新需求,Common包分析后仍然是共性需求需要實現(xiàn),那么Common包會重新編譯構建,并進行了版本升級。

在這種場景下,實際上微服務A和C兩個模塊的代碼沒有做任何修改,那么這個時候A和C是否需要重新進行編譯構建?

可以很明確的看到這個時候A和C不用進行編譯構建,而僅僅需要對微服務B進行編譯構建,B在構建的時候會自動獲取到最新的Common Jar包。

那么在這個場景下,實際的部署架構下是Common包多個版本共存。

為何要如此處理?

簡單來說微服務拆分后,需要做到的就是進行最小化的編譯構建和部署,來滿足業(yè)務需求的變化,能夠不重新構建的就不構建,不重新部署的就不部署。只有這樣才能夠更好的控制住變更范圍,也更加容易分析在版本部署后出現(xiàn)問題。

比如上圖,如果Common包升級后,微服務A也重新進行了部署構建,那么這個時候問題究竟出在哪里是很難馬上做出判斷的。

當然也存在其它的一些場景:

比如對于Common包的版本升級,雖然接口沒有變化,但是一個共性方法的實現(xiàn)邏輯出現(xiàn)了變化,這個時候必須觸發(fā)三個微服務部署目錄下的JAR包進行升級。而這個場景下本身也有兩種方式來做這個事情。

其一是三個微服務重新構建來獲取新版本Jar包

其二是將新的JAR包自動分發(fā)到三個微服務部署環(huán)境或容器中

就當前來說第一種方法很難做,往往都需要對微服務重新進行編譯構建,或者重新進行部署。也正是這個原因可以看到,當采用JAR包或SDK代理包這種方式,最大的一個問題就是版本變化的情況下的升級問題。

面向解耦而設計

微服務架構設計實踐總結和思考

前面已經(jīng)談到,不是你用了Http API接口就是松耦合,如果兩個微服務模塊之間有大量的API接口交互,那么仍然是一種緊耦合的關系。

談微服務的時候你會發(fā)現(xiàn),一個微服務要成功正常運行,有大量的底層技術組件或微服務依賴,也有大量的同層的其它微服務模塊API接口依賴。如果任何一個依賴的微服務出現(xiàn)問題,或者數(shù)據(jù)庫出現(xiàn)問題都會導致微服務無法正常運行。

不論現(xiàn)在談緩存,還是談消息中間件和事件驅動架構,你可以看到都是希望對微服務間進行解耦,對微服務和數(shù)據(jù)庫之間進行解耦。

對于核心的解耦思路實際在前面已經(jīng)談到過,即:

對于查詢,采用緩存方式進行解耦;

對于導入或CUD接口,采用消息中間件解耦;

微服務架構設計實踐總結和思考

實際上面的思路和經(jīng)常談到的CQRS命令查詢職責分離思路類似,通過CQRS一開始是為了更好的配合讀寫分離的數(shù)據(jù)庫使用。但是真正CQRS實現(xiàn)解耦的重點仍然是兩個。

其一是將命令作為事件推送到消息中間件處理,以避免出現(xiàn)長周期分布式事務。其次就是啟用單獨的R讀庫,可以是數(shù)據(jù)庫,也可以是緩存庫,來實現(xiàn)查詢功能獨立解耦和性能提升。

在實際的實踐中,不同開發(fā)團隊之間交互接口最好能夠通過消息中間件或緩存進行徹底解耦,以降低相互之間的依賴和影響。

比如對于微服務A需要推送數(shù)據(jù)到微服務B,同時需要從微服務C查詢數(shù)據(jù)。那么推送數(shù)據(jù)庫到B的接口可以實現(xiàn)為消息接口,先推送數(shù)據(jù)到消息中間件;而對于數(shù)據(jù)的查詢則可以在獲取數(shù)據(jù)后進行緩存等。

變更影響分析

微服務架構設計實踐總結和思考

在微服務架構實踐過程中,由于很多接口是采用Http API接口方式進行調(diào)用,很多接口修改實際并不會引起編譯構建期的錯誤。因此導致某個微服務接口修改后導致其它微服務模塊功能出現(xiàn)異常的情況。當出現(xiàn)問題后,我們才在事后進行修復。

對于服務鏈監(jiān)控和鏈路跟蹤是一個事后的行為,重點是發(fā)現(xiàn)性能問題而不是幫你去分析服務之間的依賴關系。

因此提前梳理清楚微服務間的接口交互和依賴關系是必須的,如上圖。

通過上圖的接口交互矩陣,可以很清楚的看到當某個接口出現(xiàn)變化的時候,究竟會對哪些微服務模塊,哪些功能造成影響,那這些影響點就必須考慮配套的變更或者說在提交測試的時候,這些影響到的微服務模塊或功能也需要進行測試。

當然如果我們在微服務架構實施過程中,已經(jīng)形成了完整的基于接口的單元測試和自動化測試,也可以更好的解決和提前發(fā)現(xiàn)問題。當你關注點在微服務模塊這個粒度的時候,很容易忽略微服務模塊間的交互和協(xié)同實際需要管控到API接口這個粒度,這是我們在實施微服務架構的時候需要重點關注的一個點。

 

文章來源:今日頭條,作者:人月聊IT;

【數(shù)商云www.zhimaihui.cn】致力于提供企業(yè)級的電子商務平臺建設服務,長期為大中型企業(yè)打造數(shù)據(jù)化、商業(yè)化、智能化的電子商務建設方案,同時我們還提供B2B電子商務平臺、B2B2C多用戶商城系統(tǒng)、B2C電子商務系統(tǒng)、跨境進口電商平臺、供應商管理系統(tǒng)、新零售電商平臺、直播電商系統(tǒng)等一系列系統(tǒng)定制開發(fā)服務。

點贊 | 0

數(shù)商云是一家全鏈數(shù)字化運營服務商,專注于提供SCM/企業(yè)采購/SRM供應商/DMS經(jīng)銷商/渠道商等管理系統(tǒng),B2B/S2B/S2C/B2B2C/B2C等電商系統(tǒng),從“供應鏈——生產(chǎn)運營——銷售市場”端到端的全鏈數(shù)字化產(chǎn)品和方案,致力于通過數(shù)字化和新技術為企業(yè)創(chuàng)造商業(yè)數(shù)字化價值。

添加企業(yè)微信獲取更多資料
添加企業(yè)微信獲取更多資料
相關文章

評論

剩余-200
發(fā)表
填寫以下信息, 免費獲取方案報價
姓名
手機號碼
企業(yè)名稱
  • 建筑建材
  • 化工
  • 鋼鐵
  • 機械設備
  • 原材料
  • 工業(yè)
  • 環(huán)保
  • 生鮮
  • 醫(yī)療
  • 快消品
  • 農(nóng)林牧漁
  • 汽車汽配
  • 橡膠
  • 工程
  • 加工
  • 儀器儀表
  • 紡織
  • 服裝
  • 電子元器件
  • 物流
  • 化塑
  • 食品
  • 房地產(chǎn)
  • 交通運輸
  • 能源
  • 印刷
  • 教育
  • 跨境電商
  • 旅游
  • 皮革
  • 3C數(shù)碼
  • 金屬制品
  • 批發(fā)
  • 研究和發(fā)展
  • 其他行業(yè)
需求描述
填寫以下信息馬上為您安排系統(tǒng)演示
姓名
手機號碼
你的職位
企業(yè)名稱

恭喜您的需求提交成功

尊敬的用戶,您好!

您的需求我們已經(jīng)收到,我們會為您安排專屬電商商務顧問在24小時內(nèi)(工作日時間)內(nèi)與您取得聯(lián)系,請您在此期間保持電話暢通,并且注意接聽來自廣州區(qū)域的來電。
感謝您的支持!

您好,我是您的專屬產(chǎn)品顧問
掃碼添加我的微信,免費體驗系統(tǒng)
(工作日09:00 - 18:00)
專屬顧問圖片
電話咨詢 (工作日09:00 - 18:00)
客服熱線: 4008 868 127
售前熱線: 189 2432 2993
掃碼即可快速撥打熱線