微服務實戰:從架構到發佈(一)

引言:“微服務”是當前軟件架構領域非常熱門的詞彙,能找到很多關於微服務的定義、準則,以及如何從微服務中獲益的文章,在企業的實踐中去應用“微服務”的資源卻很少。本篇文章中,會介紹微服務架構(Microservices
Architecture)的基礎概念,以及如何在實踐中具體應用。

單體架構(Monolithic Architecture )

企業級的應用一般都會面臨各種各樣的業務需求,而常見的方式是把大量功能堆積到同一個單體架構中去。比如:常見的ERP、CRM等系統都以單體架構的方式運行,同時由於提供了大量的業務功能,隨着功能的升級,整個研發、發佈、定位問題,擴展,升級這樣一個“怪物”系統會變得越來越困難。

單體架構的初期效率很高,應用會隨着時間推移逐漸變大。在每次的迭代中,開發團隊都會面對新功能,然後開發許多新代碼,隨着時間推移,這個簡單的應用會變成了一個巨大的怪物。

clipboard.png

圖1:單體架構

大部分企業通過SOA來解決上述問題,SOA的思路是把應用中相近的功能聚合到一起,以服務的形式提供出去。因此基於SOA架構的應用可以理解爲一批服務的組合。SOA帶來的問題是,引入了大量的服務、消息格式定義和規範。

多數情況下,SOA的服務直接相互獨立,但是部署在同一個運行環境中(類似於一個Tomcat實例下,運行了很多web應用)。和單體架構類似,隨着業務功能的增多SOA的服務會變得越來越複雜,本質上看沒有因爲使用SOA而變的更好。圖1,是一個包含多種服務的在線零售網站,所有的服務部署在一個運行環境中,是一個典型的單體架構。

單體架構的應用一般有以下特點:

設計、開發、部署爲一個單獨的單元。

會變得越來越複雜,最後導致維護、升級、新增功能變得異常困難

很難以敏捷研發模式進行開發和發佈

部分更新,都需要重新部署整個應用

水平擴展:必須以應用爲單位進行擴展,在資源需求有衝突時擴展變得比較困難(部分服務需要更多的計算資源,部分需要更多內存資源)

可用性:一個服務的不穩定會導致整個應用出問題

創新困難:很難引入新的技術和框架,所有的功能都構建在同質的框架之上

微服務架構(Microservices Architecture)

微服務架構的核心思想是,一個應用是由多個小的、相互獨立的、微服務組成,這些服務運行在自己的進程中,開發和發佈都沒有依賴。

多數人對於微服務的定義是,把本來運行在單體架構中的服務拆分成相互獨立的服務,並運行在各自的進程中。在我看來,不僅如此。最關鍵的地方在於,不同的服務能依據不同的業務需求,構建的不同的技術架構之上,並且聚焦在有限的業務功能之上。

因此,在線零售網站可以用圖2的微服務架構來簡單概括。基於業務需求,需要增加一個賬戶服務微服務,因此構建微服務絕不是在單體架構中把服務拆分開這麼簡單。

clipboard.png

圖2:微服務架構

微服務設計:規模、範圍、業務功能

你可能從零開始用微服務來構建應用,也可能重構現有系統,確定微服務的規模,範圍和功能都特別重要。讓我們討論一些有關微服務設計的關鍵問題和對它的誤解:

“微”很容易被誤解:很多開發者會傾向於把服務往儘量小的顆粒度去做

在SOA方式下,服務都還是以單體架構在運行,用於支持不同的功能。如果依舊採用SAO類似的服務,僅僅是名義上叫做微服務,並不能帶來任何微服務的優勢。

那我們在微服務中應該怎樣設計呢。以下是微服務的設計指南:

職責單一原則(Single Responsibility
Principle):把某一個微服務的功能聚焦在特定業務或者有限的範圍內會有助於敏捷開發和服務的發佈。

設計階段就需要把業務範圍進行界定。

需要關心微服務的業務範圍,而不是服務的數量和規模儘量小。數量和規模需要依照業務功能而定。

於SOA不同,某個微服務的功能、操作和消息協議儘量簡單。

項目初期把服務的範圍制定相對寬泛,隨着深入,進一步重構服務,細分微服務是個很好的做法。

微服務消息

在單體架構中,不同功能之間通信通過方法調用,或者跨語言通信。SOA降低了這種語言直接的耦合度,採用基於SOAP協議的web服務。這種web服務的功能和消息體定義都十分複雜,微服務需要更輕量的機制。

同步消息 – REST, Thrift

同步消息就是客戶端需要保持等待,直到服務器返回應答。REST是微服務中默認的同步消息方式,它提供了基於HTTP協議和資源API風格的簡單消息格式,多數微服務都採用這種方式(每個功能代表了一個資源和對應的操作)。

Thrift是另外一個可選的方案。它採用接口描述語言定義並創建服務,支持可擴展的跨語言服務開發,所包含的代碼生成引擎可以在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等創建高效的、無縫的服務,其傳輸數據採用二進制格式,相對 XML 和 JSON 體積更小,對於高併發、大數據量和多語言的環境更有優勢。

clipboard.png

圖3:REST接口,對外微服務

異步消息 – AMQP, STOMP, MQTT

異步消息就是客戶端不需要一直等待服務應答,有應到後會得到通知。某些微服務需要用到異步消息,一般採用AMQP, STOMP, MQTT。

消息格式 – JSON, XML, Thrift, ProtoBuf, Avro

消息格式是微服務中另外一個很重要的因素。SOA的web服務一般採用文本消息,基於複雜的消息格式(SOAP)和消息定義(xsd)。微服務採用簡單的文本協議JSON和XML,基於HTTP的資源API風格。如果需要二進制,通過用到Thrift, ProtoBuf, Avro。

服務約定 – 定義接口 – Swagger, RAML, Thrift IDL

如果把功能實現爲服務,併發布,需要定義一套約定。單體架構中,SOA採用WSDL,WSDL過於複雜並且和SOAP緊耦合,不適合微服務。

REST設計的微服務,通常採用Swagger和RAML定義約定。

對於不是基於REST設計的微服務,比如Thrift,通常採用IDL(Interface Definition Languages),比如Thrift IDL。

微服務集成 (服務間通信)

微服務架構下,應用的服務直接相互獨立。在一個具體的商業應用中,需要有些機制支持微服務之間通信。因此服務間的通信機制特別重要。

SOA體系下,服務之間通過企業服務總線(Enterprise Service Bus)通信,許多業務邏輯在中間層(消息的路由、轉換和組織)。微服務架構傾向於降低中心消息總線(類似於ESB)的依賴,將業務邏輯分佈在每個具體的服務終端。

大部分微服務基於HTTP、JSON這樣的標準協議,集成不同標準和格式變的不再重要。另外一個選擇是採用輕量級的消息總線或者網關,有路由功能,沒有複雜的業務邏輯。下面就介紹幾種常見的架構方式。

點對點方式 – 直接調用服務

點對點方式中,服務之間直接用。每個微服務都開放REST API,並且調用其它微服務的接口。

clipboard.png

圖4:通過點對點方式通信

很明顯,在比較簡單的微服務應用場景下,這種方式還可行,隨着應用複雜度的提升,會變得越來越不可維護。這點有些類似SOA的ESB,儘量不採用點對點的集成方式。

點對點有下面幾個缺點:

非功能的需求,比如用戶授權、限制、監控,需要在每個微服務中進行實現

隨着功能的演進,服務會變得越來越複雜。

不同的服務直接,客戶端和服務直接沒有控制功能(監控、跟蹤、過濾)

直接通信在大型系統設計中,一般是反面典型。

因此,如果設計一個大型的微服務系統,儘量避免點對點的通信方式,也不能像ESB這樣重量級的總線。而是一個輕量級的總線,能夠提供非業務功能的抽象。這就是API網關方式。

API-網關方式

API網關方式的核心要點是,所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能個。通常,網關也是提供REST/HTTP的訪問API。服務端通過API-GW註冊和管理服務。

clipboard.png

圖5:通過API-網關暴露微服務

用我們網上商店的例子,在圖5中,所有的業務接口通過API網關暴露,是所有客戶端接口的唯一入口。微服務之間的通信也通過API網關。

採用網關方式有如下優勢:

有能力爲微服務接口提供網關層次的抽象。比如:微服務的接口可以各種各樣,在網關層,可以對外暴露統一的規範接口。

輕量的消息路由、格式轉換。

統一控制安全、監控、限流等非業務功能。

每個微服務會變得更加輕量,非業務功能個都在網關層統一處理,微服務只需要關注業務邏輯

目前,API網關方式應該是微服務架構中應用最廣泛的設計模式。

消息代理方式

微服務也可以集成在異步的場景下,通過隊列和訂閱主題,實現消息的發佈和訂閱。一個微服務可以是消息的發佈者,把消息通過異步的方式發送到隊列或者訂閱主題下。作爲消費者的微服務可以從隊列或者主題共獲取消息。通過消息中間件把服務之間的直接調用解耦。

clipboard.png

圖6:異步通信方式

通常異步的生產者/消費者模式,通過AMQP、MQTT等異步消息規範。

數據的去中心化

單體架構中,不同功能的服務模塊都把數據存儲在某個中心數據庫中。

clipboard.png

圖7:單體架構,用一個數據庫存儲所有數據

微服務方式,多個服務之間的設計相互獨立,數據也應該相互獨立(比如,某個微服務的數據庫結構定義方式改變,可能會中斷其它服務)。因此,每個微服務都應該有自己的數據庫。

clipboard.png

圖8:每個微服務有自己私有的數據庫,其它微服務不能直接訪問。

數據去中心話的核心要點:

每個微服務有自己私有的數據庫持久化業務數據

每個微服務只能訪問自己的數據庫,而不能訪問其它服務的數據庫

某些業務場景下,需要在一個事務中更新多個數據庫。這種情況也不能直接訪問其它微服務的數據庫,而是通過對於微服務進行操作。

數據的去中心化,進一步降低了微服務之間的耦合度,不同服務可以採用不同的數據庫技術(SQL、NoSQL等)。在複雜的業務場景下,如果包含多個微服務,通常在客戶端或者中間層(網關)處理。
圖片描述圖片描述
下篇文章會介紹微服務實戰的其它內容:管理去中心化、服務的註冊和發現、安全、事務、失敗的設計、其它。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章