1. SOA與微服務
面向服務(SOA)已經不是一個新名詞了,跟Paxos有一樣古老的年齡,其本質是一種軟件架構的設計思想。類似“雲計算”的分層和服務提供概念(IaaS==>PaaS==>SaaS),SOA是把企業應用的業務功能以能力開放的形式提供出來,比如通過構建企業服務總線ESB來實現企業應用間的服務集成和編排。
而微服務更多的是對SOA的一種實踐方式(ESB也是SOA的一種實現方式),主要針對企業應用系統本身的架構設計做解耦和組件服務化,從業務上把原來龐大的系統拆分為多個可以獨立設計、獨立開發、獨立部署的小應用,小應用之間通過特定的交互協議(RPC/HTTP等)完成服務的暴露和調用。
關鍵詞:組件服務化,去中心化,分布式,自動化部署和發布
2. 微服務與傳統集群
傳統集群的常見架構一般是前端做負載均衡(F5、apache、nginx)反向代理一堆Web容器中的war,通常一個war就是整個應用(把整個應用放在一個進程中),后端再接統一的緩存和DB等等。而微服務的一種可能設計是前端做負載均衡,請求代理到控制層后調用部署在不同機器上的小應用來共同完成一次請求,小應用之間也會有相互的依賴調用,各個小應用本身可以有自己的緩存和DB,也可以多個小應用共用同一個持久層。
網上的一個對比圖:左邊是傳統集群,右邊是微服務,可以看到一個微服務的小應用就是一個進程,小應用之間的相互調用是通過進程間的通信實現的而不是傳統組件依賴中的代碼調用,這樣就非常方便做到分布式部署了。

在web開發和部署中的對比如下圖所示:

3. 為什么需要微服務
支撐互聯網公司快速發展的業務系統面臨着不斷的迭代,當系統規模達到一定的量級后就會發現重構是一件必須要進行但又非常痛苦甚至不可能完成的事情。系統的可擴展可伸縮性一直是架構師努力追求的目標,“業務拆分”是最自然有效的辦法,各個業務模塊相互獨立,形散而神聚,共同構建出一個功能強大的支撐系統。
參考《大型網站技術架構》當中典型的系統演進路線和設計模式,系統的發展最后都會走到分布式的路子上來,從“單工程單實例單庫”到“多工程多實例多緩存分表分庫”,系統的規模越來越龐大,復雜度也越來越高,考慮重構的時候首先從業務上尋找突破,能夠從業務角度做出拆分的話,那么就不要勉強的把系統和代碼揉合到一起,只有當系統本身作為一個獨立的業務體時還是太龐大時那么才考慮微服務。
4. 微服務實現
“開發未動 設計先行”,實現系統的微服務化需要一些先決條件和很多的准備工作,首先是系統架構的總體設計,微服務中小應用的邊界一般是原系統中的一個業務模塊,下圖是中國電信CRM3.0的總體系統架構圖,微服務層面主要是按照業務模塊划分了客賬戶中心、訂單中心、資產中心、資源中心等將近15中心化的微服務,各中心自治,獨立開發和發布,可以實現服務的快速迭代(從圖中也可以看到ESB的影子)。

網上找的一張京東IM咚咚架構圖做對比(微服務化)

實施微服務帶來系統架構的變化的同時也會帶來開發團隊組織架構的變化(這是我結合以前工作經歷畫的一個草圖)以前我們分前台組,后台組,規則組,架構組等,實施微服務后,按中心做划分,一個中心由一個小團隊負責,團隊成員可能有前台也可能有后台。

組織架構調整好后就是開發流程,微服務更多強調的是“協議先行”(報文協議先約定好,然后並行開發),以及誰開發誰維護,開發人員參與到應用的整個生命周期。
開發中一些好用的平台化工具:
自動化構建部署:Jenkins+Docker
統一日志平台:Hlog
統一配置平台:uniConfig/CMDB
統一監控管理平台:AI-HPaaS
在線API編輯和管理:ShowDoc(這個挺重要的,目前很多系統開發中接口都沒有形成文檔,導致后期維護升級很麻煩)
5. 服務治理框架
微服務要求線上系統具備水平擴展的能力,那么小應用和小應用之間的調用就不能直接寫成固定的IP地址了,這時候一般引入第三方的服務治理框架Spring Cloud /Dubbo(Dubbox)來做到服務發現、服務注冊、負載均衡、過載保護(熔斷和降級)等等。
Spring Cloud(Eureka):一般以Spring Boot為基礎實現快速構建微服務應用,應用也不再是必須打包成war部署到web容器中,而是打成jar包,直接 java -jar XXX.jar 運行。
Spring Cloud 中一些重要的組件有:Eureka、Robbion、Zuul、Hystrix、Config等等
Dubbo:注冊中心(Registry)一般可以用zookeeper或者redis等實現,通過注冊中心來實現服務的自動注冊和發現。

6. 潛力與挑戰並存
優勢:
可擴展性:解決了企業應用持久化層的瓶頸問題(關系數據庫單機性能問題以及NoSQL還不能完全替代數據庫成為持久層解決方案),同時,符合設計模式的單一職責原則,一個微服務應用本身只專注於某一個業務模塊,可以根據業務特性單獨架構和優化更新,甚至選擇不同的技術棧,而且小應用本身代碼行數少相對來說產生Bug的幾率也減少,也更利於小應用本身的測試和維護。
可用性:通過服務熔斷和降級可以有效保證應用系統的整體可用性,即使某個微服務的某個實例掛掉也不會影響系統的其他功能。同時系統可水平擴展以提高整體吞吐量來適應業務的快速發展或者是並發量的突然增加(如電商的秒殺和運營商的促銷活動等)
並行開發:因為小應用之間是解耦的,這樣就可以盡早約定接口協議然后開發人員並行開發,只要協議不變,那么服務調用方對服務提供方的變化是無感知的,這樣降低了業務模塊之間的耦合度,有利於快速構建系統的原型。
不足:
系統復雜性增加:1.整個系統的內聚性降低了,經常會出現來了某個需求,要改好幾個服務(分別由不同的小團隊配合完成),工作中也經常聽到同事訴苦“之前一句SQL就搞定的接口現在要調3/4個服務)。2.由於天生的分布式特性,勢必會帶來數據一致性的問題,這對系統架構師是個很大的挑戰(必須從業務上尋找突破口來實現最終的一致性)。3.系統工程數量急劇增加,四川電信CRM系統實施微服務后工程數量由原來的40個不到一下子增加到120+,給源碼管理和版本管控帶來了很大的挑戰。
運維難度增大:變更或升級的管理難度增大,服務之間經常是A依賴B,B依賴C,然后C又依賴其他,對於已經約定好的報文協議很難做修改(對擴展開放,對修改關閉),同時由於服務數量的增加和服務本身的無狀態帶來了服務的監控與治理變得更加復雜要依賴強大的服務治理框架。
管理難度增大:開發和測試時只能通過模擬報文或者直連的方式調用服務提供方的接口,增加了團隊溝通成本和協調管理的難度。
7. 總結
微服務架構只是金字塔尖的那一朵小紅花,需要下面一層層的Pass綠葉來陪襯。實施微服務需要基礎設施的自動化(包括自動化構建、測試、部署和監控等),同時也要求開發團隊組織架構的調整來適應新的開發模式(微服務很適合敏捷開發,可以實現快速構建快速交付,迭代發布)。
幸運的是目前Java平台已經有很多很多成熟的PaaS中間件來解決企業應用在微服務化重構時遇到的挑戰。
軟件架構總在不斷演進,微服務之后會是Service Mesh么?
