from:http://www.infoq.com/cn/articles/what-complete-micro-service-system-should-include?utm_source=infoq&utm_medium=popular_widget&utm_campaign=popular_content_list&utm_content=homepage


近幾年,微服務架構迅速在整個技術社區竄紅,它被認為是IT軟件架構的未來方向,大神Martin Fowler也給微服務極高的評價。那為什么我們需要微服務,微服務的真正優勢到底是什么,一個完整的微服務系統,應該包含哪些功能,本文作者劉彥夫在軟件設計和開發領域有10多年工作經驗,他將會從他的角度給出答案。

對微服務的基本理解

顧名思義,微服務要從兩個方面來理解,一個是“微”,一個是“服務”。體型小到一定程度才能叫“微”,這個程度是什么呢?一個身高1米6,體重90斤的MM,我們說她苗條。微服務也一樣,根據亞馬遜CEO Bezos給出的有趣定義,單個微服務的設計、開發、測試和運維的所有人加在一起吃飯,只需要兩個批薩就夠了,這是就是著名的two pizza team rule。

具備什么樣的能力才能算是“服務”?這個話題很大,我這里按照自己的片面理解總結一下,所謂服務就一定會區別于系統的功能,服務是一個或者一組相對的較小且獨立的功能單元,是用戶可以感知的功能最小集,比如:購物車,訂單,信用卡結算等都可以作為單個服務獨立提供。

這個理解顯然不夠深刻,為了進一步理解為什么微服務在近兩年業界迅速竄紅,理解為什么微服務會被認為是IT軟件架構的未來方向,就要理解為什么我們需要微服務?它能給企業帶來什么價值。傳統企業的IT軟件大多都是各種獨立系統的堆砌,這些系統的問題總結來說就是擴展性差,可靠性不高,維護成本高。后來有了一個叫SOA的軟件架構專門針對這些問題給出了一套解決方案,很多企業也因此將自身IT系統遷移到SOA架構上。

但是,由于SOA早期均使用了總線模式,這種總線模式是與某種技術棧強綁定的,比如:J2EE。這導致很多企業的遺留系統很難對接,切換時間太長,成本太高,新系統穩定性的收斂也需要一些時間。最終SOA開起來很美,但卻成為了企業級奢侈品,中小公司都望而生畏。

依然SOA

微服務,從本質意義上看,還是SOA架構。但內涵有所不同,微服務并不綁定某種特殊的技術,在一個微服務的系統中,可以有Java編寫的服務,也可以有Python編寫的服務,他們是靠Restful架構風格統一成一個系統的。

最粗淺的理解就是將微服務之間的交互看作是各種字符串的傳遞,各種語言都可以很好的處理字符串,所以微服務本身與具體技術實現無關,擴展性強。另一個不同是微服務架構本身很輕,底層也有類似于SOA的總線,不過非常輕薄,現在看到的就兩種方式:MQ和HTTP,而HTTP都不能完全等同于總線,而僅僅是個信息通道。

所以,基于這種簡單的的協議規范,無論是兼容老舊系統,還是上線新業務,都可以隨著時代的步伐,滾動升級。比如:你去年還在使用.NET技術,今年就可以平滑的過度到Go了,而且系統已有服務不用改動。所以微服務架構,既保護用戶已有投資,又很容易向新技術演進。

微服務水下的冰山

人月不是銀彈,微服務更不是銀彈,好像軟件微服務化了,軟件系統就能夠應對各種問題了。其實微服務的水面下藏著巨大的冰山。下面是微服務提供的能力,以及背后需要付出的代價。

  1. 單個微服務代碼量小,易修改和維護。但是,系統復雜度的總量是不變的,每個服務代碼少了,但服務的個數肯定就多了。就跟拼圖游戲一樣,切的越碎,越難拼出整幅圖。一個系統被拆分成零碎的微服務,最后要集成為一個完整的系統,其復雜度肯定比大塊的功能集成要高很多。

  2. 單個微服務數據獨立,可獨立部署和運行。雖然微服務本身是可以獨立部署和運行的,但仍然避免不了業務上的你來我往,這就涉及到要對外通信,當微服務的數量達到一定量級的時候,如何提供一個高效的集群通信機制成為一個問題。

  3. 單個微服務擁有自己的進程,進程本身就可以動態的啟停,為無縫升級的打好了基礎,但誰來啟動和停止進程,什么時機,選擇在哪臺設備上做這件事情才是無縫升級的關鍵。這個能力并不是微服務本身提供的,而是需要背后強大的版本管理和部署能力。

  4. 多個相同的微服務可以做負載均衡,提高性能和可靠性。正是因為相同微服務可以有多個不同實例,讓服務按需動態伸縮成為可能,在高峰期可以啟動更多的相同的微服務實例為更多用戶服務,以此提高響應速度。同時這種機制也提供了高可靠性,在某個微服務故障后,其他相同的微服務可以接替其工作,對外表現為某個設備故障后業務不中斷。同樣的道理,微服務本身是不會去關心系統負載的,那么什么時候應該啟動更多的微服務,多個微服務的流量應該如何調度和分發,這背后也有一套復雜的負載監控和均衡的系統在起作用。

  5. 微服務可以獨立部署和對外提供服務,微服務的業務上線和下線是動態的,當一個新的微服務上線時,用戶是如何訪問到這種新的服務?這就需要有一個統一的入口,新的服務可以動態的注冊到這個入口上,用戶每次訪問時可以從這個入口拿到系統所有服務的訪問地址,類似于到餐廳吃飯,新菜要寫到“菜單”中,以供用戶選擇。這個統一的系統入口并不是微服務本身的一部分,所以這種能力需要系統單獨提供。

  6. 還有一些企業級關注的系統問題,比如,安全策略如何集中管理?系統故障如何快速審計和跟蹤到具體服務?整個系統狀態如何監控?服務之間的依賴關系如何管理?等等這些問題都不是單個微服務考慮的范疇,而需要有一個系統性的考慮和設計,讓每個微服務都能夠按照系統性的要求和約束提供對應的安全性,可靠性,可維護性的能力。

綜上所述,微服務關鍵其實不僅僅是微服務本身,而是系統要提供一套基礎的架構,這種架構使得微服務可以獨立的部署、運行、升級,不僅如此,這個系統架構還讓微服務與微服務之間在結構上“松耦合”,而在功能上則表現為一個統一的整體。這種所謂的“統一的整體”表現出來的是統一風格的界面,統一的權限管理,統一的安全策略,統一的上線過程,統一的日志和審計方法,統一的調度方式,統一的訪問入口等等。

這些系統性的功能也需要有一些服務來提供,這些服務不會直接呈現給最終用戶,也就是微服務系統冰山下面的部分,我們可以簡稱它為微服務系統的“底座”。所有的微服務都像一個APP,插在這個底座的上面,享受這個底座提供的系統能力比如:元數據存放、灰度發布、藍綠部署等等。

微服務系統底座

一個完整的微服務系統,它的底座最少要包含以下功能:

  • 日志和審計,主要是日志的匯總,分類和查詢

  • 監控和告警,主要是監控每個服務的狀態,必要時產生告警

  • 消息總線,輕量級的MQ或HTTP

  • 注冊發現

  • 負載均衡

  • 部署和升級

  • 事件調度機制

  • 資源管理,如:底層的虛擬機,物理機和網絡管理

以下功能不是最小集的一部分,但也屬于底座功能:

  • 認證和鑒權

  • 微服務統一代碼框架,支持多種編程語言

  • 統一服務構建和打包

  • 統一服務測試

  • 微服務CI/CD流水線

  • 服務依賴關系管理

  • 統一問題跟蹤調試框架,俗稱調用鏈

  • 灰度發布

  • 藍綠部署

    • 令人困惑的幾個問題

    微服務的底座是不是必須的?

    是的,基本上是必須的。你可以不用代碼實現一個資源管理服務,可以手工用Excel管理你的所有機器資源,但是不代表微服務系統沒有這個功能,只不過這個功能是人工實現的。再舉個例子,日志系統如果只是簡單的打印文件,那么多個微服務的日志就需要手工收集,人工分類和篩選。所以,微服務的底座最小集一定會存在,問題是看怎樣實現它。

    這里僅僅是總結了對微服務系統的基本理解,而實現這個架構有很多技術,這里不進行詳細展開。實踐方面,推薦王磊的《微服務架構與實踐》,他描述了使用Ruby相關的技術實現了一整套微服務系統,特別是書中后面的實踐部分講解了如何將已有的系統演化為微服務架構,是很好的參考和指導材料。

    是不是所有軟件都能做微服務?

    這個命題有些微妙,也很難說清楚,回答這個命題本身就是一種挑戰,可能最終也沒有正確答案。不過,我還是把我自己的理解寫在這里,讓大家去拍磚。在我這里,答案是否定的。我只需舉出一個反例,比如:存儲系統,其架構是傳統的分層架構,每一層都使用下面一層的服務,并為上一層提供服務。雖然可以將這種架構調整為基于服務的架構,但沒辦法做成微服務。

    區別在哪里呢?核心的區別在于獨立性上,微服務大多是可以獨立的運行和使用的,而存儲這種非常底層和基礎的系統,每層部件都不能單獨被使用,比如:Pool管理、CHUNK管理、VOL管理、NFS文件系統,這些功能都無法離開另外一些功能而獨立運行,要對外提供可用的存儲功能,一大堆功能必須一起上。這種系統做到極致,最多也就能夠使其部件可以獨立的部署和升級,俗稱打熱補丁。

    這也就是為什么這種底層傳統系統架構通常是單塊架構的原因。由于單塊架構的各個部分調用關系緊密,做成微服務后系統集成成本會大大增加,不僅如此,這樣的架構做成微服務并不能提高交付效率,因為各個部分根本就無法獨立的運行和測試。

    什么樣的軟件做成微服務?

    能不能做成微服務,取決于四個要素:

    • 小:微服務體積小,2 pizza團隊。

    • 獨:能夠獨立的部署和運行。

    • 輕:使用輕量級的通信機制和架構。

    • 松:為服務之間是松耦合的。

    針對于小、輕、松都是可以通過某些技術手段達到目的,而獨立的部署和運行,則是和業務本身有關系,如果你這個系統提供的業務是貼近最終用戶的,并且這些功能之間的耦合性很小,則微服務就可以按照業務功能本身的獨立性來劃分,則這類系統做成微服務是非常合適的。如果系統提供的業務是非常底層的,如:操作系統內核、存儲系統、網絡系統、數據庫系統等等,這類系統都偏底層,功能和功能之間有著緊密的配合關系,如果強制拆分為較小的服務單元,會讓集成工作量急劇上升,并且這種人為的切割無法帶來業務上的真正的隔離,所以無法做到獨立部署和運行,也就更加無法做到真正的微服務了。


    感謝郭蕾對本文的審校。

    給InfoQ中文站投稿或者參與內容翻譯工作,請郵件至editors@cn.infoq.com。也歡迎大家通過新浪微博(@InfoQ@丁曉昀),微信(微信號:InfoQChina)關注我們。