激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

云服務(wù)器|WEB服務(wù)器|FTP服務(wù)器|郵件服務(wù)器|虛擬主機(jī)|服務(wù)器安全|DNS服務(wù)器|服務(wù)器知識|Nginx|IIS|Tomcat|

服務(wù)器之家 - 服務(wù)器技術(shù) - 服務(wù)器知識 - 微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

2020-12-28 23:23今日頭條人月聊IT 服務(wù)器知識

今天繼續(xù)談下在微服務(wù)架構(gòu)設(shè)計中的一些實踐和思考。對于SOA和微服務(wù),我前面很多文章都進(jìn)行了詳細(xì)的闡述,今天這篇文章重點還是放在一些架構(gòu)設(shè)計和實踐的一些關(guān)鍵點思考上面。

今天繼續(xù)談下在微服務(wù)架構(gòu)設(shè)計中的一些實踐和思考。對于SOA和微服務(wù),我前面很多文章都進(jìn)行了詳細(xì)的闡述,今天這篇文章重點還是放在一些架構(gòu)設(shè)計和實踐的一些關(guān)鍵點思考上面。

微服務(wù)架構(gòu)核心

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

  • 開發(fā)團(tuán)隊的拆分
  • 代碼層的拆分,可獨立構(gòu)建打包
  • 數(shù)據(jù)庫的拆分

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

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

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

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

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

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

按劃分后的子域拆分?jǐn)?shù)據(jù)庫

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

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

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

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

微服務(wù)和微服務(wù)API接口

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

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

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

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

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

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

面向API接口設(shè)計

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

這個是我在前面一直強(qiáng)調(diào)的觀點,即大型項目或傳統(tǒng)的大型單體應(yīng)用在進(jìn)行微服務(wù)化的時候,一定是架構(gòu)設(shè)計先行。架構(gòu)設(shè)計的關(guān)鍵工作就是:

  • 微服務(wù)模塊拆分,包括數(shù)據(jù)庫拆分
  • 微服務(wù)模塊暴露的API接口識別定義

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

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

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

在微服務(wù)架構(gòu)實踐中經(jīng)常看到的情況就是前期架構(gòu)設(shè)計不充分,相關(guān)的邊界劃分不明確,接口定義不明確,導(dǎo)致后期微服務(wù)在設(shè)計開發(fā)過程中持續(xù)大量的交互,同時隨意的增加和定義新的API接口,這種場景下必然帶來后續(xù)接口交互和管控治理的混亂。

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

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

構(gòu)建獨立的領(lǐng)域組合微服務(wù)

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

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

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

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

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

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

在DDD領(lǐng)域驅(qū)動設(shè)計的架構(gòu)分層里面,在領(lǐng)域?qū)由嫌幸粋€獨立的應(yīng)用層,這個應(yīng)用層即和這類談到的領(lǐng)域組合微服務(wù)對應(yīng)。而下層的領(lǐng)域?qū)觿t由多個微服務(wù)提供粗粒度的API接口服務(wù)能力。

微服務(wù)網(wǎng)關(guān)和API網(wǎng)關(guān)

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

簡單來說如果當(dāng)前微服務(wù)A模塊有100個接口服務(wù)。

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

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

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

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

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

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

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

共性基礎(chǔ)JAR包依賴

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

同時各個微服務(wù)本身以黑盒Jar包的方式對基礎(chǔ)組件包進(jìn)行依賴。

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

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

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

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

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

為何要如此處理?

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

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

當(dāng)然也存在其它的一些場景:

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

  • 其一是三個微服務(wù)重新構(gòu)建來獲取新版本Jar包
  • 其二是將新的JAR包自動分發(fā)到三個微服務(wù)部署環(huán)境或容器中

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

面向解耦而設(shè)計

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

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

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

  • 對于核心的解耦思路實際在前面已經(jīng)談到過,即:
  • 對于查詢,采用緩存方式進(jìn)行解耦
  • 對于導(dǎo)入或CUD接口,采用消息中間件解耦
微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

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

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

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

變更影響分析

微服務(wù)架構(gòu)設(shè)計實踐總結(jié)和思考

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

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

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

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

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

原文地址:http://dockone.io/article/1282027

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品一区二区三区中文字幕老牛 | 亚洲电影免费观看国语版 | 福利在线免费 | 免费a级毛片大学生免费观看 | 久久免费视屏 | 成年人免费视频播放 | 99re久久最新地址获取 | 欧美黄一区 | 男女无遮挡羞羞视频 | 亚洲一区二区三区视频免费 | 亚洲五码在线观看视频 | 国产精品久久久久久久久久久久久久久久 | 精品一区二区免费 | 成人羞羞视频在线观看 | 欧美大电影免费观看 | 亚洲精品一区二区三区免 | 国产日本在线播放 | 欧美人与禽性xxxxx杂性 | 91精品国产综合久久婷婷香 | 国产99久久久久久免费看 | 久久久青 | 一区二区久久电影 | 成人免费观看49www在线观看 | 欧洲伊人网 | 海外中文字幕在线观看 | 久久成人激情视频 | 一区二区三区欧美在线观看 | 久久毛片免费观看 | 激情综合网俺也去 | 永久免费av片在线观看全网站 | 欧美一级视频网站 | 久久久久久久久免费 | 成人永久免费视频 | 日韩精品中文字幕在线播放 | av电影直播 | 色污视频在线观看 | av性色全交蜜桃成熟时 | 九草在线 | 成人福利在线 | 欧美高清第一页 | 国产成人精品一区二区仙踪林 |