微服務(wù)究竟是“靈丹”還是“毒藥”?
點(diǎn)擊關(guān)注,與你共同成長(zhǎng)!

微服務(wù)架構(gòu)是從單體架構(gòu)演化而來的。所謂單體架構(gòu),指的是整個(gè)互聯(lián)網(wǎng)系統(tǒng)所有代碼打包在一個(gè)程序中,部署在一個(gè)集群上,一個(gè)單體應(yīng)用構(gòu)成整個(gè)系統(tǒng)。
而微服務(wù)架構(gòu)則是將這個(gè)大的應(yīng)用里面的一些模塊拆分出來,這些模塊獨(dú)立部署在一些相對(duì)較小的服務(wù)器集群上,應(yīng)用通過遠(yuǎn)程調(diào)用的方式依賴這些獨(dú)立部署的模塊完成業(yè)務(wù)處理。這些被獨(dú)立部署的模塊被稱為微服務(wù),而這樣的應(yīng)用架構(gòu)也被稱為微服務(wù)架構(gòu)。
應(yīng)該說,模塊化、低耦合一直以來都是軟件設(shè)計(jì)追求的目標(biāo),獨(dú)立部署的微服務(wù)使模塊之間的依賴關(guān)系更加清晰,隔離得也更好,讓系統(tǒng)更易于開發(fā)、維護(hù),代表了正確的技術(shù)方向。但是在實(shí)踐中,有時(shí)使用了微服務(wù)系統(tǒng)反而變得更加難以開發(fā)、維護(hù),技術(shù)團(tuán)隊(duì)痛苦不堪,覺得是微服務(wù)的“鍋”,于是主張放棄微服務(wù),退回到單體架構(gòu)。
那么,究竟該不該使用微服務(wù)?微服務(wù)是“靈丹”還是“毒藥”?
阿里巴巴大約是國內(nèi)最早嘗試微服務(wù)的企業(yè)之一。讓我們先回顧一下這段歷史,看看當(dāng)年阿里巴巴為什么要使用微服務(wù)架構(gòu)?微服務(wù)架構(gòu)能解決什么問題?用好微服務(wù)需要做哪些準(zhǔn)備?
阿里巴巴開始嘗試微服務(wù)架構(gòu)大約是在2008年。在此之前,一個(gè)網(wǎng)站就是一個(gè)大應(yīng)用,一個(gè)用Java開發(fā)的war包就包含了整個(gè)應(yīng)用。系統(tǒng)更新時(shí),即使只是更新其中極小的一部分,也要重新打包整個(gè)war包,發(fā)布整個(gè)系統(tǒng)。
隨著業(yè)務(wù)的不斷發(fā)展,這樣的單體巨無霸系統(tǒng)遇到了越來越多的困難。
1. 編譯、部署困難
一個(gè)應(yīng)用系統(tǒng)一個(gè)war包,這個(gè)war包的大小可能是幾個(gè)GB。對(duì)于開發(fā)工程師來說,開發(fā)編譯和部署這個(gè)war包都是非常困難的,當(dāng)時(shí)我用自己的電腦編譯,大約花了半個(gè)多小時(shí)。工程師在開發(fā)的過程中,即使只改了龐大系統(tǒng)中的一行代碼,也必須重新打包完整的系統(tǒng)才能做開發(fā)測(cè)試。對(duì)這樣的單體系統(tǒng)進(jìn)行開發(fā)部署和測(cè)試都是非常困難的,有時(shí)甚至一天都寫不了幾行代碼。
2. 代碼分支管理困難
因?yàn)閱误w應(yīng)用非常龐大,所以代碼模塊也是由多個(gè)團(tuán)隊(duì)共同維護(hù)的,但最后還是要編譯成一個(gè)單體應(yīng)用,統(tǒng)一發(fā)布。這就要求把各個(gè)團(tuán)隊(duì)的代碼合并在一起,這個(gè)過程很容易發(fā)生代碼沖突。而合并的時(shí)候又是應(yīng)用要發(fā)布的時(shí)候,發(fā)布本就是復(fù)雜的過程,再加上代碼合并帶來的風(fēng)險(xiǎn),各種情況糾纏在一起,極易出錯(cuò)。所以,在單體應(yīng)用時(shí)代,每一次應(yīng)用發(fā)布都需要搞到深更半夜。
3. 數(shù)據(jù)庫連接耗盡
對(duì)于一個(gè)巨型的應(yīng)用而言,因?yàn)橛写罅康挠脩暨M(jìn)行訪問,所以必須部署到大規(guī)模的服務(wù)器集群上,且每個(gè)應(yīng)用都需要與數(shù)據(jù)庫建立連接。大量的應(yīng)用服務(wù)器連接到數(shù)據(jù)庫,會(huì)對(duì)數(shù)據(jù)庫的連接產(chǎn)生巨大的壓力,某些情況下甚至?xí)谋M數(shù)據(jù)庫的連接。
4. 新增業(yè)務(wù)困難
因?yàn)樗械臉I(yè)務(wù)都耦合在一個(gè)單一的大系統(tǒng)里,隨著時(shí)間的推移,這個(gè)系統(tǒng)會(huì)變得非常復(fù)雜,想要維護(hù)這樣一個(gè)系統(tǒng)是非常困難的。很多新入職的工程師不熟悉業(yè)務(wù),于是熟悉系統(tǒng)的老員工要加班加點(diǎn)地干活,不熟悉系統(tǒng)的新員工雖然一幫忙就出亂,但也免不了要跟著加班。整個(gè)公司熱火朝天地干活,但最后還是常常出故障,新的功能遲遲不能上線。
5. 發(fā)布困難
單體系統(tǒng)一個(gè)war包就包含了所有的代碼,新版本發(fā)布的時(shí)候,即使跟自己開發(fā)的代碼一點(diǎn)關(guān)系都沒有,但就因?yàn)榘俗约旱拇a,所以也不得不跟著發(fā)布值班,真正更新代碼功能的只有幾個(gè)人,他們汗流浹背地處理代碼沖突和修復(fù)發(fā)布Bug,沒有代碼更新的同事則陪著聊天、打瞌睡、打游戲。
這些單體架構(gòu)帶來的問題很多工程師都是有切身體會(huì)的。所以,在開始重構(gòu)微服務(wù)架構(gòu)時(shí),雖然也遇到了很多挑戰(zhàn)和困難,但是大家為了自身的利益,還是團(tuán)結(jié)一致,成功完成了微服務(wù)架構(gòu)重構(gòu)。
當(dāng)時(shí),阿里自己開發(fā)了一個(gè)微服務(wù)框架重構(gòu)微服務(wù)架構(gòu),這個(gè)微服務(wù)框架就是著名的Dubbo。Dubbo借鑒了此前更早的SOA架構(gòu)方案,即面向服務(wù)的體系架構(gòu)。SOA架構(gòu)如圖27-1所示。

Dubbo在借鑒SOA架構(gòu)的基礎(chǔ)上進(jìn)行了優(yōu)化,拋棄了SOA一些不必要的規(guī)范約束,使用二進(jìn)制協(xié)議進(jìn)行服務(wù)注冊(cè)與調(diào)用,這使得執(zhí)行效率和使用的簡(jiǎn)潔性都得到了極大提升。Dubbo架構(gòu)如圖27-2所示。

Dubbo架構(gòu)和SOA架構(gòu)一樣,最核心的組件也是三個(gè),分別是服務(wù)提供者、服務(wù)消費(fèi)者和服務(wù)注冊(cè)中心。
顧名思義,服務(wù)的提供者就是微服務(wù)的具體提供者,它通過微服務(wù)容器對(duì)外提供服務(wù),而服務(wù)的消費(fèi)者就是應(yīng)用系統(tǒng)或是其他微服務(wù)。
具體過程是服務(wù)的提供者程序在Dubbo的服務(wù)容器中啟動(dòng),通過服務(wù)管理容器向服務(wù)注冊(cè)中心進(jìn)行注冊(cè),聲明服務(wù)提供者提供的接口參數(shù)和規(guī)范,并且注冊(cè)自己所在服務(wù)器的IP地址和端口。
服務(wù)的消費(fèi)者如果想要調(diào)用某個(gè)服務(wù),只需依賴服務(wù)提供者的接口進(jìn)行編程即可。而服務(wù)接口通過Dubbo框架的代理訪問機(jī)制,調(diào)用Dubbo的服務(wù)框架客戶端,服務(wù)框架客戶端會(huì)根據(jù)服務(wù)接口聲明,去注冊(cè)中心查找對(duì)應(yīng)的服務(wù)提供者啟動(dòng)在哪些服務(wù)器上,并且將這個(gè)服務(wù)器列表返回給客戶端??蛻舳烁鶕?jù)某種負(fù)載均衡策略,選擇某一個(gè)服務(wù)器,通過遠(yuǎn)程通信模塊發(fā)送具體的服務(wù)調(diào)用請(qǐng)求。
服務(wù)調(diào)用請(qǐng)求通過Dubbo底層的遠(yuǎn)程通信模塊,也就是RPC調(diào)用方式,將請(qǐng)求發(fā)送到服務(wù)的提供者服務(wù)器,服務(wù)提供者服務(wù)器收到請(qǐng)求以后,將該請(qǐng)求發(fā)送給服務(wù)提供者程序,執(zhí)行服務(wù),并將服務(wù)執(zhí)行的結(jié)果通過遠(yuǎn)程調(diào)用通信模塊RPC返回給服務(wù)消費(fèi)者客戶端,服務(wù)消費(fèi)者客戶端將結(jié)果返回給服務(wù)調(diào)用程序,從而完成遠(yuǎn)程服務(wù)的調(diào)用,獲得服務(wù)處理的結(jié)果。
微服務(wù)架構(gòu)的落地實(shí)踐

微服務(wù)和業(yè)務(wù)的關(guān)系是非常緊密的,僅僅用好微服務(wù)技術(shù)框架是無法成功實(shí)施微服務(wù)的。成功實(shí)施微服務(wù)最重要的是做好業(yè)務(wù)的模塊化設(shè)計(jì),模塊之間要低耦合、高聚合,模塊之間的依賴關(guān)系要清晰簡(jiǎn)單。只有實(shí)現(xiàn)這樣的模塊化設(shè)計(jì),才能構(gòu)建出良好的微服務(wù)架構(gòu)。如果系統(tǒng)本身就是一團(tuán)糟,強(qiáng)行將它們拆分在不同的微服務(wù)里,只會(huì)使系統(tǒng)變得更加混亂。

面經(jīng)美團(tuán)暑期實(shí)習(xí)Java一面二面
程序員缺乏經(jīng)驗(yàn)的 7 種表現(xiàn)
以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯(cuò)的,歡迎「分享」「贊」或者點(diǎn)擊「在看」支持,謝謝各位。
