微服務(wù)的“月之暗面”

"嫦娥4號"航天器剛剛首次登陸“月之暗面”,國人歡欣鼓舞。我也湊個熱鬧,說一說微服務(wù)的“月之暗面”。


圖片發(fā)自簡書App


微服務(wù)的迅速推廣有原因的。從國內(nèi)各公司遇到的問題來看,一般都是處于快速成長期的互聯(lián)網(wǎng)公司,不論是流量、用戶數(shù)和訂單、業(yè)務(wù)的種類,還是運營的復(fù)雜度上來說,都遇到瓶頸。由于前期不注重質(zhì)量,技術(shù)團隊當(dāng)仁不讓的成為問責(zé)對象——開發(fā)進度慢,“上個線就崩”,成為普遍現(xiàn)象。系統(tǒng)“耦合”嚴(yán)重,一般是上下共識。

怎么拆?——微服務(wù)聽上去是個靈丹妙藥。

正好在技術(shù)上,Spring框架[2]和基于Web的SOA和REST架構(gòu)[3]經(jīng)過十多年的發(fā)展,日趨成熟。解決注冊發(fā)現(xiàn)、負(fù)載均衡、熔斷降級等機制的開源框架不斷涌現(xiàn),比如Eureka, Zookeeper, Hystrix等等。Netflix本身等其他公司的“成功經(jīng)驗”也作為微服務(wù)的實例印證。

如果把微服務(wù)當(dāng)作一個產(chǎn)品,從營銷角度來看的話,它作為一個新鮮事物,聽上去簡單易懂(實則似懂非懂),工程師上手快體現(xiàn)技術(shù)高水平,又有架構(gòu)師們的號召,還有國內(nèi)外技術(shù)輿論支撐,完全滿足作為一個爆款的前提條件。

微服務(wù)應(yīng)用到了2018年下半年,突然聽到看到很多抱怨,其中不少也是凡普趟過的經(jīng)驗教訓(xùn)。主要體現(xiàn)在以下幾個方面:

1. 測試?yán)щy
2. 部署困難
3. 運維困難

表現(xiàn)形式上都是各微服務(wù)系統(tǒng)交互復(fù)雜:一個一個的“微“服務(wù)之間的調(diào)用關(guān)系是什么?這令測試時可能不充分,不能覆蓋大部分用例;令部署和運維時不知道依賴關(guān)系,說好拆分后不相互影響實際上還是相互影響,而且還不能第一時間像大泥球時代一樣被發(fā)現(xiàn)。

這凸顯了一個微服務(wù)架構(gòu)中,如何切分微服務(wù),或者邊界問題。

于是又去找仙丹。這回是領(lǐng)域驅(qū)動設(shè)計Domain-Driven Design (DDD)[4]。有按名詞分的,按動詞分的,但是其實沒有明確的切分標(biāo)準(zhǔn)。又有方法論比如Event Storming [5]。Alberto Brandolini來京的時候我還專門討教了我的疑問。對于簡單的業(yè)務(wù)和模型,任何一種方法都是有效的,但是我發(fā)現(xiàn)對于實際復(fù)雜的業(yè)務(wù)場景,特別是國內(nèi)這種各大公司什么都想做的情況,沒有答案。

我倒反而釋然了——微服務(wù)架構(gòu)還是要回歸到建模和對業(yè)務(wù)深入理解的架構(gòu)本質(zhì)工作上來,按照業(yè)務(wù)屬性,以及康威定律[6]。微服務(wù)只是一種切分邊界和團隊責(zé)任的方式,語言中的根據(jù)包package或者jar包的切分也是一種方式,只是物理上,微服務(wù)的隔離做得更好一些。

隔離形成約束是工程上常見的一種做法。比如對于編程,Clean Architecture [7] 中說到:

1. 結(jié)構(gòu)化編程是對程序控制權(quán)的直接轉(zhuǎn)移的規(guī)范和限制
2. 面向?qū)ο缶幊?OOP)是對程序控制權(quán)的間接轉(zhuǎn)移的規(guī)范和限制
3. 函數(shù)式編程是(FP)對程序賦值操作的規(guī)范和限制

其中,OOP似乎就是對應(yīng)名詞劃分的邊界,F(xiàn)P就是對應(yīng)動詞劃分的邊界,而整個微服務(wù)就是一個結(jié)構(gòu)化編程。

所以微服務(wù),作為一種松散的架構(gòu),必須對應(yīng)著響應(yīng)的規(guī)范、原則,也就是服務(wù)治理,比如服務(wù)發(fā)現(xiàn)網(wǎng)關(guān)(Gateway)是一種方式,杜絕除REST以外的IPC調(diào)用也是一種方式。微服務(wù)是需要為“失敗”設(shè)計,并且以演進的方式設(shè)計的。Martin Fowler的原文中說得好,不再贅述。

因為微服務(wù)實質(zhì)上是一種隔離措施,而容器化是近些年操作系統(tǒng)層面資源隔離做得最好的,所以容器化及其管理是一個必須。

復(fù)雜的交互需要各微服務(wù)正本清源,注冊發(fā)現(xiàn)自己,版本化發(fā)布服務(wù)也是一個必須。

測試自動化,特別是串起各微服務(wù)的回歸測試自動化,雖然很奢侈不好做,也是一個必須。

實時系統(tǒng)監(jiān)控上,需要各服務(wù)的調(diào)用鏈路的可視化。

另外常常忽視的是,團隊組織上,需要綁定微服務(wù)的責(zé)任制。這不是在事故時要追究團隊的責(zé)任,而是在服務(wù)治理發(fā)現(xiàn)中方便找到響應(yīng)的團隊解決問題,還有就是在頻繁的組織變動中避免出現(xiàn)微服務(wù)“孤兒”。

最后給大家提個醒,在建立微服務(wù)的過程中盡量避免以下問題:

1. “為了拆而拆”,架構(gòu)是為了提供穩(wěn)定可持續(xù)發(fā)展的業(yè)務(wù),而不是為了美麗的架構(gòu);
2. “只管生不管養(yǎng)”,也就是說要建立微服務(wù)的可持續(xù)維護和運營的機能:版本化,監(jiān)控等等;

想一想,大家在實施微服務(wù)中出現(xiàn)的問題,其實是軟件工程中普遍的問題,并非為微服務(wù)特有,但是任何架構(gòu)和方法都有“月之暗面”。每一個工程師都必須有他的“嫦娥4號”去發(fā)現(xiàn)。全盤肯定和全盤否定都是“Too Simple, Too Naive"的表現(xiàn)。

References

[1] Microservices, James Lewis and Martin Fowler, https://martinfowler.com/articles/microservices.html
[2] Spring框架,https://spring.io/
[3] REpresentational State Transfer (REST). https://restfulapi.net/
[4] DDD手冊, Eric Evans, https://domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf
[5] Event Storming, Alberto Brandolini, https://www.eventstorming.com/
[6] Conway's Law, Melvin E. Conway, http://www.melconway.com/Home/Conways_Law.html
[7] Clean Architecture, Robert C. Marin

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容