1. 程式人生 > >從單體架構、到SOA、再到微服務的架構設計詳解

從單體架構、到SOA、再到微服務的架構設計詳解

本文涉及的內容以及知識點如下:

  1. 單體架構
  2. 單體架構的拆分
  3. SOA與微服務的區別
  4. 微服務的優缺點
  5. 微服務的訊息
  6. 服務整合
  7. 資料的去中心化

單體架構
Web應用程式發展的早期,大部分web工程是將所有的功能模組(service side)打包到一起並放在一個web容器中執行,很多企業的Java應用程式打包為war包。其他語言(Ruby,Python或者C++)寫的程式也有類似的問題。假設你正在構建一個線上商店系統:客戶下訂單、核對清單和信用卡額度,並將貨物運輸給客戶。很快,你們團隊一定能構造出如下圖所示的系統。
在這裡插入圖片描述
這種將所有功能都部署在一個web容器中執行的系統就叫做單體架構(也叫:巨石型應用)。單體架構有很多好處:IDE都是為開發單個應用設計的、容易測試——在本地就可以啟動完整的系統、容易部署——直接打包為一個完整的包,拷貝到web容器的某個目錄下即可執行。但是,上述的好處是有條件的:應用不那麼複雜。對於大規模的複雜應用,單體架構應用會顯得特別笨重:要修改一個地方就要將整個應用全部部署(PS:在不同的場景下優勢也變成了劣勢);編譯時間過長;迴歸測試周期過長;開發效率降低等。另外,單體架構不利於更新技術框架,除非你願意將系統全部重寫(代價太高你願意老闆也不願意)。
單體架構的拆分


詳細一個網站在業務大規模爬升時會發生什麼事情?併發度不夠?OK,加web伺服器。資料庫壓力過大?OK,買更大更貴的資料庫。資料庫太貴了?將一個表的資料分開儲存,俗稱“分庫分表”。這些都沒有問題,good job。不過,老外的抽象能力比我們強,看下圖Fig2。
在這裡插入圖片描述
這張圖從三個維度概括了一個系統的擴充套件過程:
(1)x軸,水平復制,即在負載均衡伺服器後增加多個web伺服器;
(2)z軸擴充套件,是對資料庫的擴充套件,即分庫分表(分庫是將關係緊密的表放在一臺資料庫伺服器上,分表是因為一張表的資料太多,需要將一張表的資料通過hash放在不同的資料庫伺服器上);
(3)y軸擴充套件,是功能分解,將不同職能的模組分成不同的服務。從y軸這個方向擴充套件,才能將巨型應用分解為一組不同的服務,例如訂單管理中心、客戶資訊管理中心、商品管理中心等等。
SOA與微服務

SOA:服務導向式架構(SOA)是整合多個較大元件(一般是應用)的一種機制,它們將整體構成一個彼此協作的套件。一般來說,每個元件會從始至終執行一塊完整的業務邏輯,通常包括完成整體大action所需的各種具體任務與功能。元件一般都是鬆耦合的,但這並非SOA架構模式的要求。
微服務:是一種架構設計模式
在微服務架構中,業務邏輯被拆分成一系列小而鬆散耦合的分散式元件,共同構成了較大的應用。每個元件都被稱為微服務,而每個微服務都在整體架構中執行著單獨的任務,或負責單獨的功能。每個微服務可能會被一個或多個其他微服務呼叫,以執行較大應用需要完成的具體任務;系統還為任務執行——比如搜尋或顯示圖片任務,或者其他可能需要多次執行的任務提供了統一的解決處理方式,並限制應用內不同地方生成或維護相同功能的多個版本。

  • 1). 負責單個功能
  • 2). 單獨部署
  • 3). 包含一個或多個程序
  • 4). 擁有自己的資料儲存
  • 5). 一支小團隊就能維護幾個微服務
  • 6). 可替換的

相對於SOA,區別如下:
在這裡插入圖片描述
SOA嘗試將應用整合,一般採用中央管理模式來確保各應用能夠互動運作。微服務嘗試部署新功能,快速有效地擴充套件開發團隊。它著重於分散管理、程式碼再利用與自動化執行。
微服務的優缺點
微服務架構模式有很多好處。
**第一,通過分解巨大單體應用為多個服務方法解決了複雜性問題。**在功能不變的情況下,應用被分解為多個可管理的分支或服務。每個服務都有一個用 RPC- 或者訊息驅動 API 定義清楚的邊界。
**第二,這種架構使得每個服務都可以有專門開發團隊來開發。**開發者可以自由選擇開發技術,提供 API 服務。
**第三,微服務架構模式使得每個微服務獨立部署,開發者不再需要協調其它服務部署對本服務的影響。**最後,微服務架構模式使得每個服務獨立擴充套件。你可以根據每個服務的規模來部署滿足需求的實利。微服務架構也有不足。其中一個跟他的名字類似,“微服務”強調了服務大小,實際上,有一些開發者鼓吹建立稍微大一些的,10-100 LOC服務組。儘管小服務更樂於被採用,但是不要忘了微服務只是結果,而不是最終目的。微服務的目的是有效的拆分應用,實現敏捷開發和部署。另外一個不足之處在於,微服務應用是分散式系統,由此會帶來固有的複雜性。開發者需要在 RPC 或者訊息傳遞之間選擇並完成程序間通訊機制。此外,他們必須寫程式碼來處理訊息傳遞中速度過慢或者不可用等區域性失效問題。另外一個關於微服務的挑戰來自於分割槽的資料庫架構。同時更新多個業務主體的事務很普遍。這種事務對於單體式應用來說很容易,因為只有一個數據庫。在微服務架構應用中,需要更新不同服務所使用的不同的資料庫。測試一個基於微服務架構的應用也是很複雜的任務。另外一個挑戰在於,微服務架構模式應用的改變將會波及多個服務。部署一個微服務應用也很複雜,一個單體應用只需要在複雜均衡器後面部署各自的伺服器就好了。每個應用例項是需要配置諸如資料庫和訊息中介軟體等基礎服務。每個服務都有多個例項,這就形成大量需要配置、部署、擴充套件和監控的部分。除此之外,你還需要完成一個服務發現機制(後續文章中發表),以用來發現與它通訊服務的地址(包括伺服器地址和埠)
微服務訊息
1)同步訊息 – REST, Thrift
同步訊息就是客戶端需要保持等待,直到伺服器返回應答。REST是微服務中預設的同步訊息方式,它提供了基於HTTP協議和資源API風格的簡單訊息格式,多數微服務都採用這種方式(每個功能代表了一個資源和對應的操作)。Thrift是另外一個可選的方案。它採用介面描述語言定義並建立服務,支援可擴充套件的跨語言服務開發,所包含的程式碼生成引擎可以在多種語言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等建立高效的、無縫的服務,其傳輸資料採用二進位制格式,相對 XML 和 JSON 體積更小,對於高併發、大資料量和多語言的環境更有優勢。
2)非同步訊息 – AMQP, STOMP, MQTT
非同步訊息就是客戶端不需要一直等待服務應答,有應到後會得到通知。某些微服務需要用到非同步訊息,一般採用AMQP, STOMP, MQTT。
3)訊息格式 – JSON, XML, Thrift, ProtoBuf, Avro
訊息格式是微服務中另外一個很重要的因素。SOA的web服務一般採用文字訊息,基於複雜的訊息格式(SOAP)和訊息定義(xsd)。微服務採用簡單的文字協議JSON和XML,基於HTTP的資源API風格。如果需要二進位制,通過用到Thrift, ProtoBuf, Avro。
4)服務約定 – 定義介面 – 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這樣的標準協議,整合不同標準和格式變的不再重要。另外一個選擇是採用輕量級的訊息匯流排或者閘道器,有路由功能,沒有複雜的業務邏輯。下面就介紹幾種常見的架構方式。
1)、點對點方式 – 直接呼叫服務
點對點方式中,服務之間直接用。每個微服務都開放REST API,並且呼叫其它微服務的介面。
在這裡插入圖片描述
圖:通過點對點方式通訊很明顯,在比較簡單的微服務應用場景下,這種方式還可行,隨著應用複雜度的提升,會變得越來越不可維護。這點有些類似SOA的ESB,儘量不採用點對點的整合方式。
2)、API-閘道器方式
API閘道器方式的核心要點是,所有的客戶端和消費端都通過統一的閘道器接入微服務,在閘道器層處理所有的非業務功能個。通常,閘道器也是提供REST/HTTP的訪問API。服務端通過API-GW註冊和管理服務。圖:通過API-閘道器暴露微服務
在這裡插入圖片描述
用我們網上商店的例子,在圖5中,所有的業務介面通過API閘道器暴露,是所有客戶端介面的唯一入口。微服務之間的通訊也通過API閘道器。
採用閘道器方式有如下優勢:
a.有能力為微服務介面提供閘道器層次的抽象。比如:微服務的介面可以各種各樣,在閘道器層,可以對外暴露統一的規範介面。
b.輕量的訊息路由、格式轉換。
c.統一控制安全、監控、限流等非業務功能。
d.每個微服務會變得更加輕量,非業務功能個都在閘道器層統一處理,微服務只需要關注業務邏輯目前,API閘道器方式應該是微服務架構中應用最廣泛的設計模式。
3)、訊息代理方式
微服務也可以整合在非同步的場景下,通過佇列和訂閱主題,實現訊息的釋出和訂閱。一個微服務可以是訊息的釋出者,把訊息通過非同步的方式傳送到佇列或者訂閱主題下。作為消費者的微服務可以從佇列或者主題共獲取訊息。通過訊息中介軟體把服務之間的直接呼叫解耦。
在這裡插入圖片描述
圖:非同步通訊方式通常非同步的生產者/消費者模式,通過AMQP、MQTT等非同步訊息規範。
資料去中心化
單體架構中,不同功能的服務模組都把資料儲存在某個中心資料庫中。
在這裡插入圖片描述
圖:單體架構,用一個數據庫儲存所有資料微服務方式,多個服務之間的設計相互獨立,資料也應該相互獨立(比如,某個微服務的資料庫結構定義方式改變,可能會中斷其它服務)。因此,每個微服務都應該有自己的資料庫。
在這裡插入圖片描述
圖:每個微服務有自己私有的資料庫,其它微服務不能直接訪問。
資料去中心話的核心要點:
1)、每個微服務有自己私有的資料庫持久化業務資料
2)、每個微服務只能訪問自己的資料庫,而不能訪問其它服務的資料庫
3)、某些業務場景下,需要在一個事務中更新多個數據庫。這種情況也不能直接訪問其它微服務的資料庫,而是通過對於微服務進行操作。
資料的去中心化,進一步降低了微服務之間的耦合度,不同服務可以採用不同的資料庫技術(SQL、NoSQL等)。在複雜的業務場景下,如果包含多個微服務,通常在客戶端或者中間層(閘道器)處理。寫在最後,提及架構,沒有絕對最好的架構,只有最適合業務的架構。技術架構應該從業務中來,到業務中去,其抽象於業務而高於業務。作為技術開發的我們,不能一味的追求架構而架構,我們必須在公司業務發展,團隊資源中間做一個合適的選擇,然後隨著業務的發展逐步重構與優化。