重新理解微服務

追尋北極發表於2017-11-03

原文地址:http://mp.weixin.qq.com/s/41ZYIcewANWtLSnXTrDh4g

當前微服務很熱,大家都號稱在使用微服務架構,但究竟什麼是微服務架構?微服務架構是不是發展趨勢?對於這些問題,我們都缺乏清楚的認識,本文基於作者在大型網際網路系統的服務化實踐和思考,和大家一起探討微服務架構。本文主要內容包括:

  1. 傳統SOA架構

  2. 新型SOA架構

  3. 服務設計方式

  4. 深入微服務

  5. 微服務體系

  6. 微服務系統架構

傳統SOA架構

說到微服務,離不開SOA,兩者經常放一起討論,首先我們要了解SOA架構。

國外資訊化起步較早,很多大公司先後建設了很多系統,比如從開始的ERP,到OA系統,到CRM系統等。由於這些系統往往由不同的供應商提供,採用不同的技術,實施的時候也沒預先考慮到和現有系統整合,因此係統整合非常困難。

在2000年初的時候,兩個概念非常流行,一個是EAI(Enterprise application integration),即企業應用整合;還有一個是EII(Enterprise application integration),即企業資訊整合。一個從應用的角度,一個從資料的角度,本質是一回事,都是怎麼把孤立的系統整合在一起。

SOA架構源自於企業內部異構系統的整合,具體做法是各個系統對外提供粗粒度的服務,外部系統可以通過相對標準的技術訪問,大致結構如下圖所示:

每個遺留系統提供服務,該服務作為系統的前置代理,對外提供訪問。所有這些服務部署在一箇中心化的平臺,稱之為企業服務匯流排ESB(Enterprise Service Bus),ESB提供複雜處理,包括:

  • 外部訪問

    為滿足不同客戶端訪問需求,提供各種各樣的訪問協議,如WebService、HTTP、FTP、Email等,其中WebService是最典型的通訊協議。

  • 內部處理

    請求進來後,需要一系列複雜處理,如對通訊協議的解析,資料的序列化和反序列化,業務流程的編排和服務路由等。

2008年的時候,eBay基於Axis,開發了自己的SOA框架,各個系統通過建立服務,對外提供功能。如後臺搜尋系統,本身是C++開發,通過對外提供Java服務,最終以WebService的方式,方便其他系統(大多是Java)呼叫搜尋的功能。經過1年多的時間,整個SOA平臺已經有上百個服務,很大程度上方便了系統相互整合。

但我們可以看到,ESB是一個很重的機制。首先通訊方式複雜,前後端涉及多種協議,由於每次呼叫代價很高,服務一般提供粗粒度的介面,一次性儘量完成更多處理。

ESB的中心化帶來了單點故障隱患,服務統一在ESB上進行部署,也限制了服務的水平擴充套件;此外ESB還包含很多業務相關的功能,如業務流程編排等,限制了業務擴充套件的靈活性。

無論對於服務的提供者還是使用者,通過ESB這種方式整合,開發代價大,通訊效率低,因此這種傳統很重的SOA架構並沒有得到大規模應用。

新型SOA架構

這裡應用直接呼叫服務,無需經過複雜的中心節點,使用輕量級的協議,一般是HTTP,資料格式也很簡單,比如JSON,由服務提供者直接解析協議和資料格式。同時每個服務本身包含核心的業務封裝,提供給多個應用場景。

此外每個服務獨立部署,提供更好的靈活性,包括業務功能擴充套件和處理容量水平擴充套件。

我們可以看到,新型SOA和傳統基於ESB的SOA相反,這裡是強化服務終端能力,弱化通道連線。

服務如何設計

隨著網際網路業務越來越複雜,新型的SOA架構不斷深入發展,出現了多種服務設計模式。

1. 面向業務系統服務設計

面向業務系統SOA把原單體應用裡的業務邏輯層剝離出來,作為單獨的服務對外提供。

舉一個電商的例子,這裡有兩個應用,顧客使用的商品詳情頁,展示商品的資訊、商品庫存,商品價格;下單頁供顧客下單,涉及商品查詢、庫存扣減、生成訂單等。

頁面應用和服務關係如下圖所示:

商品詳情服務主要面向商品詳情頁提供資料介面,包括商品基本資訊、價格資訊、庫存資訊,介面經常根據頁面需要,聚合這幾部分資訊,提供粗粒度服務,服務底層自由訪問所需要的表。

訂單服務主要面向下單頁,其中商品資訊可以通過商品詳情服務獲取,無需單獨訪問庫表。而對於庫存,這裡是扣庫存場景,需要自己訪問庫存表,訂單資訊也是如此。

面向業務系統的服務設計是比較直接的,每個服務針對自己的“主應用”提供粗粒度服務,總體上看應用/服務/庫表是多對多的關係,如果服務設計得不好,容易導致整體網狀依賴,修改時,往往牽一髮動全身。此外對於新業務,需要單獨構建對應的服務,不利於業務創新。

2. 面向細分主題服務

面向特定主題/概念/要素構建細分服務,最終服務於該主題相關的所有業務場景,比如圍繞使用者構建使用者服務,對外供所有需要使用者資訊的業務系統訪問,內部只訪問使用者相關的幾張表,結構如下圖所示:

面向細分主題的服務對資料是獨佔式訪問,不允許其它服務訪問自己的表,也不訪問外部的表,更好地實現對該主題相關的業務規則和底層資料的封裝。

3. 面向基礎系統服務

面向基礎系統服務遮蔽底層硬體的訪問細節,以更友好更透明地方式對外提供訪問,如簡訊服務、儲存服務、快取服務等。我們一直講軟體即服務,現在更進一步,硬體也是服務。

通常面向基礎系統服務通過底層系統的叢集或多路由,提供更可靠,更強處理能力的服務。

深入微服務

微服務概念是Martin Fowler在2014年丟擲,文中給出微服務的一系列特徵,但並沒有給出準確定義。大家分別有自己的理解,還沒有共識,基於本人的服務化實踐,我覺得微服務有兩大思想。

1. 簡單連線

通過傳統SOA方式連線客戶端和服務端,是非常痛苦的,涉及傳統很重的通訊協議(DCOM/RMI/CORBA/WebService等)和複雜的資料格式(二進位制/XML等)。在連線通道方面,微服務很輕,一般採用輕量級的通訊協議(如HTTP)和簡單資料格式(如JSON)。

微服務無需中心節點提供複雜處理,特別是業務相關的處理,把業務的職責還給服務端,更靈活地響應業務變化。微服務構建好後,應該象水電煤一樣到處可用,沒有技術障礙,不同語言都可以互相呼叫。

2. 分散管理

分而治之是處理複雜問題的有效手段,微服務對系統拆分尤為徹底,在多個方面實現對系統的分散管理:

  • 分散業務

    微服務聚焦細分業務領域,是對應業務規則的唯一入口,它把整體業務分割成一個個高內聚的小業務,簡化業務之間依賴關係。

  • 分散資料

    微服務獨佔式訪問對應的資料,服務和資料是一體的。它把整體資料分割成一塊塊資料,資料塊內部的表緊密相關,塊間資料相關性弱。在實施層面,每部分資料獨立schema,邏輯上分離,或者使用獨立資料庫,物理上隔離。

  • 分散物理資源

    藉助虛擬機器和容器技術,一臺物理機可以切分為多套環境,非常適合微服務部署,對伺服器資源更高效地利用,同時有些微服務面向基礎硬體封裝,提升了對物理資源的管理。

我們可以看到,傳統的基於ESB的服務不屬於微服務範疇,它既不體現簡單連線,也不體現分散管理(ESB甚至通過流程編排對業務集中管理)。相對於傳統重的SOA服務,新型SOA,無論是面向業務系統服務,面向細分主題服務,面向基礎系統服務都符合簡單連線的特性,因此都可以算微服務的範疇。

特別地,面向細分主題服務很好體現業務和資料的分散管理,面向基礎系統服務很好體現物理資源的分散管理,因此這兩者更好地滿足微服務思想,是更純粹的微服務。

這裡是一個電商庫存微服務的例項,希望幫助大家深入瞭解微服務,大型B2C電商的庫存概念比較複雜,包括:

  • 物理庫存(倉庫裡的實際庫存)

  • 虛擬庫存(倉庫裡沒有,但可以假裝有,先拿出來賣,比如新版iPhone預售)

  • 活動庫存(總庫存裡拿出一部分做活動,提供優惠價格促銷)

  • 共享庫存(北京的庫存可以共享出來,放到上海賣)

  • 凍結庫存(庫存暫時被凍結部分,比如已下單但未發貨,此時前臺不可賣)

對於前臺來說,使用者可看到的庫存計算規則如下:

可售庫存=本地庫存(實際-凍結)+虛擬庫存(虛擬-凍結)+兄弟倉庫共享庫存(共享-凍結)

對於具體活動場景來說,可售庫存的規則不一樣,它等於活動庫存。

商品庫存是電商的核心資料,有數十個業務系統呼叫,大促時每天呼叫數十億次,往往在數百臺虛擬機器/容器上部署,提供水平擴充套件,具體架構如下:

庫存微服務化設計有很多好處:

統一業務規則

庫存的計算規則很複雜,不同業務場景看到的庫存數量都不一樣,庫存微服務通過提供唯一的庫存訪問入口,統一對庫存相關規則進行封裝,方便各個業務場景使用,如果庫存規則有變化,變化也侷限於庫存微服務內部,外部業務程式碼保持不變。

一致資料模型

庫存微服務只訪問庫存相關的四張表,它不訪問外部庫表,也不允許外部應用直接訪問這幾張表,收斂了對這些表的訪問入口,避免各個業務直接往表裡加欄位,導致資料模型混亂。

此外,這些表獨立成庫,再加上只有庫存服務訪問,資料庫連線數可以大大減少,避免資料庫連線數不夠。

各種內部優化

庫存微服務彙總所有讀寫介面,內部可以做各種優化。比如快取,由於所有寫場景都在這裡,可以通過寫後馬上更新方式,保證快取的實時一致性。所有讀場景也在這裡,可以通過合理設計,一個快取滿足多個讀場景需求,提升快取使用效率。

庫存的變化是非常重要的系統狀態變化,庫存微服務在各個庫存變化點,提供庫存變化訊息通知,以統一的訊息命名方式和訊息格式,保證相關方能夠方便地接收庫存訊息。

水平擴充套件

庫存服務每天訪問量很大,通過微服務方式可以很方便地水平擴充套件,服務本身是部署在標準的虛擬機器或容器內,通過雲的方式可以動態收縮和擴容,1號店在大促的時候,就經常以租用公有云伺服器的方式實現服務能力擴充套件。

大家可以看到,微服務很適用業務高度複雜、業務共享性高、併發量大的場景,在電商,類似的場景還有訂單/商品/使用者/價格/支付等等,我們可以圍繞這些細分概念構造微服務。

微服務體系

隨著服務的不斷構建,一個完整的微服務體系如下圖所示:

最底下是基礎系統的服務,這些服務實現對底層系統功能的封裝,供之上各個業務使用,如簡訊/訊息/儲存等服務,上層服務無需關注底層資源的物理位置和內部細節。

之上的共享服務基於細分主題,封裝企業各個維度的核心資料資源和業務規則,偏下層產品/使用者/訂單等都是主資料,共享性更強,偏上層的積分/抵用券/發票等,為某幾個業務系統所使用,規則相對也更簡單。

系統服務為企業整體系統提供基礎技術平臺,共享服務提供基礎業務平臺,兩者一起奠定企業資訊系統的基礎。最上面的業務服務基於兩大基礎平臺,面向具體的業務系統提供服務。

在這裡,服務形成了明確的分層,呼叫規則如下:

  • 上層可以呼叫下層,比如共享服務呼叫系統服務,也可以跨層呼叫,比如業務服務直接呼叫系統服務。

  • 同層方面,業務服務可以互相呼叫,組成更粗粒度服務,共享服務和系統服務都是細分服務,相互之間垂直正交,不允許相互呼叫。

通過服務細分和服務分層,微服務的職責定位明確,依賴關係清晰,總體上,整個系統變成層次化的依賴,而不是網狀依賴。

微服務系統架構

下圖是一個大型B2C電商系統實際的架構,上層是各種業務應用,底層是大量服務,並且服務分為應用服務(面向業務)和基礎服務(面向共享主題),一個非常典型的微服務架構。

當前隨著網路通訊技術的完善和雲端計算的流行,包括容器化部署,客觀上,很好地解決微服務技術上的問題;主觀上,網際網路系統體量大、業務複雜,通過微服務的方式對系統進行深入拆分是很自然的選擇。

微服務通過簡單連線簡化技術實現,通過分散管理簡化業務依賴,很好地平衡了技術複雜性和業務複雜性,在大型網際網路公司已經遍地開花。

作者介紹

王慶友,前1號店首席架構師,先後就職於eBay、騰訊、1號店等公司,精通電商業務,擅長複雜系統業務建模和架構分析,同時在構建大規模的分散式系統方 面有豐富實踐,尤其在大型系統的SOA改造方面有很深入的理論和實踐。目前在尋找新的工作機會,微訊號Brucetwins,歡迎一起聊架構。

相關文章