您好,登錄后才能下訂單哦!
提到微服務(wù),服務(wù)拆分是繞不過去的話題,但是微服務(wù)不是說拆就能拆的,需要很多的前提條件。
首先,首先在基礎(chǔ)設(shè)施層面,要有一個(gè)持續(xù)集成的平臺(tái),使得服務(wù)在拆分的過程中,功能的一致性,這種一致性不能通過人的經(jīng)驗(yàn)來,而需要經(jīng)過大量的回歸測(cè)試集,并且持續(xù)的拆分,持續(xù)的演進(jìn),持續(xù)的集成,從而保證系統(tǒng)時(shí)刻處于可以驗(yàn)證交付的狀態(tài),而非閉門拆分一段時(shí)間,最終誰也不知道功能最終究竟有沒有bug,因而需要另外一個(gè)月的時(shí)間專門修改bug。
其次在接入層,API和UI要?jiǎng)屿o分離,API由API網(wǎng)關(guān)統(tǒng)一的管理,這樣后端無論如何拆分,可以保證對(duì)于前端來講,統(tǒng)一的入口,而且可以實(shí)現(xiàn)拆分過程中的灰度發(fā)布,路由分發(fā),流量切分,從而保證拆分的平滑進(jìn)行。而且拆分后的微服務(wù)之間,為了高性能,是不建議每次調(diào)用都進(jìn)行認(rèn)證鑒權(quán)的,而是在API網(wǎng)關(guān)上做統(tǒng)一的認(rèn)證鑒權(quán),一旦進(jìn)入網(wǎng)關(guān),服務(wù)之間的調(diào)用就是可信的。
其三對(duì)于數(shù)據(jù)庫,需要進(jìn)行良好的設(shè)計(jì),不應(yīng)該有大量的聯(lián)合查詢,而是將數(shù)據(jù)庫當(dāng)成一個(gè)簡單的key-value查詢,復(fù)雜的聯(lián)合查詢通過應(yīng)用層,或者通過Elasticsearch進(jìn)行。如果數(shù)據(jù)庫表之間耦合的非常嚴(yán)重,其實(shí)服務(wù)拆分是拆不出來的。
其四要做應(yīng)用的無狀態(tài)化,只有無狀態(tài)的應(yīng)用,才能橫向擴(kuò)展,這樣拆分才有意義。
那么, 滿足了服務(wù)拆分的基礎(chǔ)設(shè)施前提之后,我們應(yīng)該先拆哪個(gè)模塊,后拆哪個(gè)模塊呢?在什么情況下一個(gè)模塊應(yīng)該拆分出來呢?
切記,微服務(wù)拆分絕非一個(gè)大躍進(jìn)運(yùn)動(dòng),由高層發(fā)起,把一個(gè)應(yīng)用拆分的七零八落的,最終大大增加運(yùn)維成本,但是并不會(huì)帶來收益。
滿足上述基本條件后,我們還要看業(yè)務(wù)變化,才能找到拆分的最佳時(shí)機(jī)。
第一,有快速迭代的需求。
互聯(lián)網(wǎng)產(chǎn)品的特點(diǎn)就是迭代速度快,一般一年半就能決出勝負(fù),第一一統(tǒng)天下,第二被第一收購,其他死翹翹。所以快速上線,快速迭代,就是生命線,而且一旦成功就是百億身家,所以無論付出多大運(yùn)維成本,使用微服務(wù)架構(gòu)都是值得的。
這也就是為什么大部分使用微服務(wù)架構(gòu)的都是互聯(lián)網(wǎng)企業(yè),因?yàn)閷?duì)于這些企業(yè)來講收益明顯。而對(duì)于很多傳統(tǒng)的應(yīng)用,半年更新一次,企業(yè)運(yùn)營相對(duì)平穩(wěn),IT系統(tǒng)的好壞對(duì)于業(yè)務(wù)沒有關(guān)鍵性影響,在他們眼中,微服務(wù)化改造帶來的效果,還不如開發(fā)多加幾次班。
第二,提交代碼頻繁出現(xiàn)大量沖突
微服務(wù)對(duì)于快速迭代的效果,首先是開發(fā)獨(dú)立,如果是一單體應(yīng)用,幾百人開發(fā)一個(gè)模塊,如果使用GIT做代碼管理,則經(jīng)常會(huì)遇到的事情就是代碼提交沖突。
同樣一個(gè)模塊,你也改,他也改,幾百人根本沒辦法溝通。所以當(dāng)你想提交一個(gè)代碼的時(shí)候,發(fā)現(xiàn)和別人提交的沖突了,于是因?yàn)槟闶呛筇峤坏娜?,你有?zé)任去merge代碼,好不容易merge成功了,等再次提交的時(shí)候,發(fā)現(xiàn)又沖突了,你是不是很惱火。隨著團(tuán)隊(duì)規(guī)模越大,沖突概率越大。
所以應(yīng)該拆分成不同的模塊,每十個(gè)人左右維護(hù)一個(gè)模塊,也即一個(gè)工程,首先代碼沖突的概率小多了,而且有了沖突,一個(gè)小組一吼,基本上問題就解決了。
每個(gè)模塊對(duì)外提供接口,其他依賴模塊可以不用關(guān)注具體的實(shí)現(xiàn)細(xì)節(jié),只需要保證接口正確就可以。
第三,小功能要積累到大版本才能上線,上線開總監(jiān)級(jí)別大會(huì)
微服務(wù)對(duì)于快速迭代的效果,首先是上線獨(dú)立。如果沒有拆分微服務(wù),每次上線都是一件很痛苦的事情。當(dāng)你修改了一個(gè)邊角的小功能,但是你不敢馬上上線,因?yàn)槟阋蕾嚨钠渌K才開發(fā)了一半,你要等他,等他好了,也不敢馬上上線,因?yàn)榱硪粋€(gè)被依賴的模塊也開發(fā)了一半,當(dāng)所有的模塊都耦合在一起,互相依賴,誰也沒辦法獨(dú)立上線,而是需要總監(jiān)協(xié)調(diào)各個(gè)團(tuán)隊(duì),大家開大會(huì),約定一個(gè)時(shí)間點(diǎn),無論大小功能,死活都要這天上線。
這種模式導(dǎo)致上線的時(shí)候,單次上線的需求列表非常長,這樣風(fēng)險(xiǎn)比較大,可能小功能的錯(cuò)誤會(huì)導(dǎo)致大功能的上線不正常,將如此長的功能,需要一點(diǎn)點(diǎn)check,非常小心,這樣上線時(shí)間長,影響范圍大。因而這種的迭代速度快不了,頂多一個(gè)月一次就不錯(cuò)了。
服務(wù)拆分后,在接口穩(wěn)定的情況下,不同的模塊可以獨(dú)立上線。這樣上線的次數(shù)增多,單次上線的需求列表變小,可以隨時(shí)回滾,風(fēng)險(xiǎn)變小,時(shí)間變短,影響面小,從而迭代速度加快。
對(duì)于接口要升級(jí)部分,保證灰度,先做接口新增,而非原接口變更,當(dāng)注冊(cè)中心中監(jiān)控到的調(diào)用情況,發(fā)現(xiàn)接口已經(jīng)不用了,再刪除。
微服務(wù)解決的問題還有高并發(fā)。互聯(lián)網(wǎng)一個(gè)產(chǎn)品的特點(diǎn)就是在短期內(nèi)要積累大量的用戶,這甚至比營收和利潤還重要,如果沒有大量的用戶基數(shù),融資都會(huì)有問題。
因而對(duì)于并發(fā)量不大的系統(tǒng),進(jìn)行微服務(wù)化的驅(qū)動(dòng)力差一些,如果只有不多的用戶在線,多線程就能解決問題,最多做好無狀態(tài)化,前面部署個(gè)負(fù)載均衡,單體應(yīng)用部署多份。
第四,橫向擴(kuò)展流程復(fù)雜,主要業(yè)務(wù)和次要業(yè)務(wù)耦合
單體應(yīng)用無狀態(tài)化之后,雖然通過部署多份,可以承載一定的并發(fā)量,但是資源非常浪費(fèi)。因?yàn)橛械臉I(yè)務(wù)是需要擴(kuò)容的,例如下單和支付,有的業(yè)務(wù)是不需要擴(kuò)容的,例如注冊(cè)。如果一起擴(kuò)容,消耗的資源可能是拆分后的幾倍,成本可能多出幾個(gè)億。而且由于配置復(fù)雜,在同一個(gè)工程里面,往往在配置文件中是這樣組織的,這一塊是這個(gè)模塊的,下一塊是另一個(gè)模塊的,這樣擴(kuò)容的時(shí)候,一些邊角的業(yè)務(wù),也是需要對(duì)配置進(jìn)行詳細(xì)審核,否則不敢貿(mào)然擴(kuò)容。
第五,熔斷降級(jí)全靠if-else
在高并發(fā)場(chǎng)景下,我們希望一個(gè)請(qǐng)求如果不成功,不要占用資源,應(yīng)該盡快失敗,盡快返回,而且希望當(dāng)一些邊角的業(yè)務(wù)不正常的情況下,主要業(yè)務(wù)流程不受影響。這就需要熔斷策略,也即當(dāng)A調(diào)用B,而B總是不正常的時(shí)候,為了讓B不要波及到A,可以對(duì)B的調(diào)用進(jìn)行熔斷,也即A不調(diào)用B,而是返回暫時(shí)的fallback數(shù)據(jù),當(dāng)B正常的時(shí)候,再放開熔斷,進(jìn)行正常的調(diào)用。
有時(shí)候?yàn)榱吮WC核心業(yè)務(wù)流程,邊角的業(yè)務(wù)流程,如評(píng)論,庫存數(shù)目等,人工設(shè)置為降級(jí)的狀態(tài),也即默認(rèn)不調(diào)用,將所有的資源用于大促的下單和支付流程。
如果核心業(yè)務(wù)流程和邊角業(yè)務(wù)流程在同一個(gè)進(jìn)程中,就需要使用大量的if-else語句,根據(jù)下發(fā)的配置來判斷是否熔斷或者降級(jí),這會(huì)使得配置異常復(fù)雜,難以維護(hù)。
如果核心業(yè)務(wù)和邊角業(yè)務(wù)分成兩個(gè)進(jìn)程,就可以使用標(biāo)準(zhǔn)的熔斷降級(jí)策略,配置在某種情況下,放棄對(duì)另一個(gè)進(jìn)程的調(diào)用,可以進(jìn)行統(tǒng)一的維護(hù)。
總之,微服務(wù)拆分的過程,應(yīng)該是一個(gè)由痛點(diǎn)驅(qū)動(dòng)的,是業(yè)務(wù)真正遇到了快速迭代和高并發(fā)的問題。如果不拆分,將對(duì)于業(yè)務(wù)的發(fā)展帶來影響,只有這個(gè)時(shí)候,微服務(wù)的拆分才有確定收益,增加的運(yùn)維成本才值得。
(本文作者為:網(wǎng)易云首席架構(gòu)師 劉超)
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。