
微服務(wù)是銀彈嗎?自2014年“微服務(wù)”一詞真是越來越火,不談Microservices彷佛就out了,那么我們先來看微服務(wù)具有哪些特點(diǎn):
- 組件以服務(wù)的形式提供
- 圍繞業(yè)務(wù)功能進(jìn)行組織
- 強(qiáng)化終端與弱化管道
- 產(chǎn)品而不是項目
- 獨(dú)立布署
- 單一職責(zé)
- 去中心化
- DevOps與組織架構(gòu)
我要講的故事開始了
A公司的技術(shù)架構(gòu)體系目前還是以集群擴(kuò)展體系為主,我們可以看下圖所示,在這種體系結(jié)構(gòu)中,可以看到應(yīng)用都是單塊結(jié)構(gòu),但是單塊結(jié)構(gòu)的應(yīng)用具有擴(kuò)展性,通過布署在多個Tomcat上實(shí)現(xiàn)應(yīng)用的集群,所有的應(yīng)用都去訪問同一個數(shù)據(jù)庫(這個庫可以假設(shè)為Oracle數(shù)據(jù)庫),數(shù)據(jù)庫間采用DataGuard來實(shí)現(xiàn)主從同步,讀庫只具有讀取功能,為后臺數(shù)據(jù)統(tǒng)計功能提供數(shù)據(jù)查詢和統(tǒng)計服務(wù)。目前業(yè)務(wù)請求的并發(fā)量每分鐘有幾十筆交易,看起來這套架構(gòu)還是能夠支撐目前的業(yè)務(wù)發(fā)展的。

突然有一天客戶在做活動的時候,監(jiān)控中心各種告警,在每分鐘500tps的時候很多請求超時,監(jiān)控顯示目前的服務(wù)器不能支撐這么大的并發(fā)量,于是快速增加服務(wù)器布署應(yīng)用上線,發(fā)現(xiàn)根本沒用,加了和沒加一樣,加幾臺都一樣,運(yùn)維和DBA發(fā)現(xiàn)此時的數(shù)據(jù)庫壓力非常大,好不容易熬過這段是時間后,團(tuán)隊成員痛定思痛一致認(rèn)為,目前的架構(gòu)體系已經(jīng)不能支持業(yè)務(wù)的發(fā)展,微服務(wù)開始快速推進(jìn)。
其中微服務(wù)的數(shù)據(jù)去中心化核心要點(diǎn)是:
- 每個微服務(wù)有自己私有的數(shù)據(jù)庫持久化業(yè)務(wù)數(shù)據(jù)。
- 每個微服務(wù)只能訪問自己的數(shù)據(jù)庫,而不能訪問其它服務(wù)的數(shù)據(jù)庫。
- 某些業(yè)務(wù)場景下,需要在一個事務(wù)中更新多個數(shù)據(jù)庫。這種情況也不能直接訪問其它微服務(wù)的數(shù)據(jù)庫,而是通過對于微服務(wù)進(jìn)行操作。
- 數(shù)據(jù)的去中心化,進(jìn)一步降低了微服務(wù)之間的耦合度。
最終經(jīng)過服務(wù)化改進(jìn)后,變成了如下圖所示的樣子:

上圖看起來是不是很棒,服務(wù)拆分是不是很清晰?
于是問題隨后就來了:
1、以前團(tuán)隊一共就10個人只負(fù)責(zé)一二個項目,現(xiàn)在突然增加到平均每人維護(hù)二三個項目,上線還是采用由運(yùn)維手工打war包上線,如果有修改的配置文件,則運(yùn)維同學(xué)一臺一臺的進(jìn)行修改,不僅容易上線出錯,而且每次上線都會搞到半夜。
2、根據(jù)上面提到的數(shù)據(jù)去中心化原則,數(shù)據(jù)庫拆分出來了,一個服務(wù)一個數(shù)據(jù)庫實(shí)例,但是對后臺統(tǒng)計系統(tǒng)來說就是惡夢,數(shù)據(jù)庫拆分出來了統(tǒng)計工作、報表工作該怎么辦呢?這部分工作還做不做呢?有人說可以分開統(tǒng)計啊,一個庫一個庫的來,可是這樣的工作量將是巨大的。
3、機(jī)房的雙活問題,對于金融公司來說雙活還是很關(guān)鍵的一項技術(shù)指標(biāo),對于應(yīng)用雙活來說,其實(shí)還是比較容易實(shí)現(xiàn),但是對于數(shù)據(jù)庫來說確是一個技術(shù)問題了,對于oracle數(shù)據(jù)庫來說,用oracle官方提供的OGG(Oracle GoldenGate)來進(jìn)行數(shù)據(jù)同步的話,根據(jù)論壇上面查看的資料可以看出,OGG坑非常多,而且也容易丟數(shù)據(jù),更重要的是貴。。。采用oracle的logminer來進(jìn)行同步,同步的數(shù)據(jù)將不是實(shí)時的,會有一定延時而且在定時讀取方面的工作上還需要自己進(jìn)行開發(fā),采用oracle的DataGuard也只能做主從同步,卻不能做主主雙活。于是通過調(diào)研過后,最終還是決定自己獨(dú)立開發(fā)。
4、使用Dubbo或者Spring cloud就是微服務(wù)了嗎?好吧,使用了Dubbo以后發(fā)現(xiàn)還有非常多的工作需要做,Dubbo只是一個服務(wù)治理框架而已,還需要開發(fā)分布式調(diào)用監(jiān)控系統(tǒng)、統(tǒng)一配置管理中心,統(tǒng)一定時調(diào)度,還要在每個服務(wù)中做防重冪等,還要做并發(fā)限流,緩存也要根據(jù)不同的服務(wù)做隔離等等工作。。。
那我們用Spring cloud做一個大一統(tǒng)的整合可以嗎?于是看到Spring cloud原來有這些坑啊:
- 注冊IP問題
早期的Spring Cloud Eureka在注冊獲取網(wǎng)卡IP時,不能區(qū)分外網(wǎng)網(wǎng)卡和內(nèi)網(wǎng)網(wǎng)卡,如果安裝了虛擬機(jī)和docker也不能區(qū)分虛擬網(wǎng)卡,每次啟動注冊的IP都有可能不一樣,如果要注冊為外網(wǎng)網(wǎng)卡IP,那運(yùn)行帶寬就不夠,這個bug應(yīng)該說是比較嚴(yán)重的問題,因此重寫了網(wǎng)卡IP獲取的邏輯來解決,同時也反饋給了spring cloud團(tuán)隊,再后期的版本中添加了網(wǎng)卡接口排序和通過名稱過濾的功能來得到解決。
- HealthCheck的問題
在一些極小概率的情況下,會導(dǎo)致Eureka Server 下線微服務(wù)實(shí)例,出現(xiàn)“Remote status from Eureka server is down”的問題,即便是重啟微服務(wù)也無濟(jì)于事,不過已經(jīng)有碼友在spring cloud 官方github貼出了解決方法的issue。
- Feign使用不當(dāng)帶來的性能問題
其他的小坑也就忍了,大坑卻不能。。。。于是去各大社區(qū)討論發(fā)現(xiàn)原來大家都對Cloud的不少組件進(jìn)行了二次封裝。。。
回顧一下
上面用了很大的篇幅各種吐槽,那么我們說微服務(wù)好嗎?我一直堅持認(rèn)為微服務(wù)很好,但是如果我們?yōu)榱耸褂梦⒎?wù)而使用的話將會傷其自身,從單塊系統(tǒng)到微服務(wù)的是需要逐步演進(jìn)的過程,如果前期沒有調(diào)研,沒有一個整體規(guī)劃,后期在做的時候會發(fā)現(xiàn),需要做的事情只會越來越多,尤其是對于快速發(fā)展的創(chuàng)業(yè)型公司來說。另外針對項目上線的問題,根據(jù)微服務(wù)的發(fā)展來說使用devops進(jìn)行CI和CD后就可以解決現(xiàn)有問題,還可以采用Docker解決容器化問題,但圍繞微服務(wù)所做的周邊工作確實(shí)巨大的工作量,換句話說,我們不懂Docker怎么辦,這就需要大量的時間來做研究和試錯,當(dāng)然如果公司很有錢也可以購買這樣的服務(wù),總之成本是很高的。
就拿我上面舉的例子來看,數(shù)據(jù)庫自身壓力大,經(jīng)過分析看出其實(shí)是很多sql沒有加索引,大量使用數(shù)據(jù)庫悲觀鎖,大表的數(shù)據(jù)一直長期積累沒有遷移出去所致。當(dāng)單塊系統(tǒng)遇到了性能問題后,如果認(rèn)真分析了性能的根源,也許還會為我們做服務(wù)化演進(jìn)爭取了更多的時間。
最后想說一句,對于中小公司來說,如果業(yè)務(wù)發(fā)展非??焖伲藛T不足的情況下,我們更需要的是在業(yè)務(wù)發(fā)展和架構(gòu)優(yōu)化間做平衡,逐步演進(jìn),而不是快速使用。