微服務架構:Dubbo VS Spring Cloud

AlbenXie發表於2018-08-09

前言

  微服務架構是網際網路很熱門的話題,是網際網路技術發展的必然結果。它提倡將單一應用程式劃分成一組小的服務,服務之間互相協調、互相配合,為使用者提供最終價值。雖然微服務架構沒有公認的技術標準和規範或者草案,但業界已經有一些很有影響力的開源微服務架構框架提供了微服務的關鍵思路,例如 Dubbo 和 Spring Cloud,各大網際網路公司也有自研的微服務框架,但其模式都於這二者相差不大。微服務主要的優勢如下

  • 降低複雜度

將原來偶合在一起的複雜業務拆分為單個服務,規避了原本複雜度無止境的積累。每一個微服務專注於單一功能,並通過定義良好的介面清晰表述服務邊界。每個服務開發者只專注服務本身,通過使用快取、DAL 等各種技術手段來提升系統的效能,而對於消費方來說完全透明。

  • 可獨立部署

由於微服務具備獨立的執行程式,所以每個微服務可以獨立部署。當業務迭代時只需要釋出相關服務的迭代即可,降低了測試的工作量同時也降低了服務釋出的風險。

  • 容錯

在微服務架構下,當某一元件發生故障時,故障會被隔離在單個服務中。 通過限流、熔斷等方式降低錯誤導致的危害,保障核心業務正常執行。

  • 擴充套件

單塊架構應用也可以實現橫向擴充套件,就是將整個應用完整的複製到不同的節點。當應用的不同元件在擴充套件需求上存在差異時,微服務架構便體現出其靈活性,因為每個服務可以根據實際需求獨立進行擴充套件。

  本文主要圍繞微服務的技術選型、通訊協議、服務依賴模式、開始模式、執行模式等幾方面來綜合比較 Dubbo 和 Spring Cloud 這 2 種開發框架。架構師可以根據公司的技術實力並結合專案的特點來選擇某個合適的微服務架構平臺,以此穩妥地實施專案的微服務化改造或開發程式。

1 核心部件

  微服務的核心要素在於服務的發現、註冊、路由、熔斷、降級、分散式配置,基於上述幾種必要條件對 Dubbo 和 Spring Cloud 做出對比。

1.1 總體架構

Dubbo 核心部件,如下圖所示:

  • Provider: 暴露服務的提供方,可以通過jar或者容器的方式啟動服務;
  • Consumer:呼叫遠端服務的服務消費方;
  • Registry: 服務註冊中心和發現中心;
  • Monitor: 統計服務和呼叫次數,呼叫時間監控中心,Dubbo 的控制檯頁面中可以顯示,目前只有一個簡單版本;
  • Container:服務執行的容器。

Spring Cloud 總體架構,如下圖所示:

  • Service Provider: 暴露服務的提供方;
  • Service Consumer:呼叫遠端服務的服務消費方;
  • Eureka Server: 服務註冊中心和服務發現中心。

點評:從整體架構上來看,二者模式接近,都需要服務提供方、服務消費方和註冊中心。

1.2 微服務架構核心要素

  Dubbo 只是實現了服務治理,而 Spring Cloud 子專案分別覆蓋了微服務架構下的眾多部件,而服務治理只是其中的一個方面。Dubbo 提供了各種 Filter,對於上述中“無”的要素,可以通過擴充套件 Filter 來完善。例如,

  • 分散式配置:可以使用淘寶的 diamond、百度的 disconf 來實現分散式配置管理;
  • 服務跟蹤:可以使用京東開源的 Hydra,或者擴充套件 Filter 用 Zippin 來做服務跟蹤;
  • 批量任務:可以使用噹噹開源的 Elastic-Job、tbschedule。

點評:從核心要素來看,Spring Cloud 更勝一籌,在開發過程中只要整合 Spring Cloud 的子專案就可以順利的完成各種元件的融合,而 Dubbo 卻需要通過實現各種 Filter 來做定製,開發成本以及技術難度略高。

2 通訊協議

基於通訊協議層面對 2 種框架支援的協議型別以及執行效率方面進行比較。

2.1 支援協議

Dubbo:Dubbo 使用 RPC 通訊協議,提供序列化方式如下,

  • Dubbo:Dubbo 預設協議採用單一長連線和 NIO 非同步通訊,適合於小資料量大併發的服務呼叫,以及服務消費者機器數遠大於服務提供者機器數的情況;
  • RMI:RMI 協議採用 JDK 標準的java.rmi.*實現,採用阻塞式短連線和 JDK 標準序列化方式;
  • Hessian:Hessian 協議用於整合 Hessian 的服務,Hessian 底層採用 Http 通訊,採用 Servlet 暴露服務,Dubbo 預設內嵌 Jetty 作為伺服器實現。
  • Http:採用 Spring 的 HttpInvoker 實現
  • Webservice:基於 CXF 的 frontend-simple 和 transports-http 實現。

Spring Cloud:Spring Cloud 使用 HTTP 協議的 REST API.

2.2 效能比較

使用一個 POJO 物件包含 10 個屬性,請求 10 萬次,Dubbo 和 Spring Cloud 在不同的執行緒數量下,每次請求耗時(ms)如下:

說明:客戶端和服務端配置均採用阿里雲的 ECS 伺服器,4 核 8G 配置,Dubbo 採用預設的 Dubbo 協議

點評:Dubbo 支援各種通訊協議,而且消費方和服務方使用長連結方式互動,通訊速度上略勝 Spring Cloud,如果對於系統的響應時間有嚴格要求,長連結更合適。

3 服務依賴方式

Dubbo:服務提供方與消費方通過介面的方式依賴,服務呼叫設計如下,

  • Interface層:服務介面層,定義了服務對外提供的所有介面;
  • Molel層:服務的 DTO 物件層;
  • Business層:業務實現層,實現 Interface 介面並且和 DB 互動。

因此需要為每個微服務定義了各自的 Interface 介面,並通過持續整合釋出到私有倉庫中,呼叫方應用對微服務提供的抽象介面存在強依賴關係,開發、測試、整合環境都需要嚴格的管理版本依賴。

通過 Maven 的install & deploy命令把 Interface 和 Model 層釋出到倉庫中,服務呼叫方只需要依賴 Interface 和 Model 層即可。在開發除錯階段只發布 Snapshot 版本,等到服務除錯完成再發布 Release 版本,通過版本號來區分每次迭代的版本。通過 XML 配置方式即可方面接入 Dubbo,對程式無入侵。

Spring Cloud:服務提供方和服務消費方通過 JSON 方式互動,因此只需要定義好相關 JSON 欄位即可,消費方和提供方無介面依賴。通過註解方式來實現服務配置,對於程式有一定入侵。

點評:Dubbo 服務依賴略重,需要有完善的版本管理機制,但是程式入侵少。而 Spring Cloud 通過 JSON 互動,省略了版本管理的問題,但是具體欄位含義需要統一管理,自身 Rest API 方式互動,為跨平臺呼叫奠定了基礎。

4 元件執行流程

下圖中的每個元件都是需要部署在單獨的伺服器上,gateWay 用來接受前端請求、聚合服務,並批量呼叫後臺原子服務。每個 Service 層和單獨的 DB 互動。

Dubbo,

  • gateWay:前置閘道器,具體業務操作,gateWay 通過 Dubbo 提供的負載均衡機制自動完成;
  • Service:原子服務,只提供該業務相關的原子服務;
  • Zookeeper:原子服務註冊到 Zookeeper 上。

Spring Cloud,

  • 所有請求都統一通過 API 閘道器(Zuul)來訪問內部服務;
  • 閘道器接收到請求後,從註冊中心(Eureka)獲取可用服務;
  • 由 Ribbon 進行均衡負載後,分發到後端的具體例項;
  • 微服務之間通過 Feign 進行通訊處理業務。

點評:業務部署方式相同,都需要前置一個閘道器來隔絕外部直接呼叫原子服務的風險。Dubbo 需要自己開發一套 API 閘道器,而 Spring Cloud 則可以通過 Zuul 配置即可完成閘道器定製。使用方式上 Spring Cloud 略勝一籌。

5 微服務架構組成以及注意事項

到底使用是 Dubbo 還是 Spring Cloud 其實並不重要,重點在於如何合理的利用微服務。下面是一張網際網路通用的架構圖,其中每個環節都是微服務的核心部分。

5.1 架構分解

  • 閘道器叢集:資料的聚合、實現對接入客戶端的身份認證、防報文重放與防資料篡改、功能呼叫的業務鑑權、響應資料的脫敏、流量與併發控制等;

  • 業務叢集:一般情況下移動端訪問和瀏覽器訪問的閘道器需要隔離,防止業務耦合;

  • Local Cache:由於客戶端訪問業務可能需要呼叫多個服務聚合,所以本地快取有效的降低了服務呼叫的頻次,同時也提示了訪問速度。本地快取一般使用自動過期方式,業務場景中允許有一定的資料延時。

  • 服務層:原子服務層,實現基礎的增刪改查功能,如果需要依賴其他服務需要在 Service 層主動呼叫;

  • Remote Cache:訪問 DB 前置一層分散式快取,減少 DB 互動次數,提升系統的 TPS;

  • DAL:資料訪問層,如果單表資料量過大則需要通過 DAL 層做資料的分庫分表處理;

  • MQ:訊息佇列用來解耦服務之間的依賴,非同步呼叫可以通過 MQ 的方式來執行;

  • 資料庫主從:服務化過程中必要的階段,用來提升系統的 TPS。

5.2 注意事項

  • 服務啟動方式建議使用jar方式啟動,啟動速度快,更容易監控;

  • 快取、快取、快取,系統中能使用快取的地方儘量使用快取,通過合理的使用快取可以有效的提高系統的 TPS;

  • 服務拆分要合理,儘量避免因服務拆分而導致的服務迴圈依賴;

  • 合理的設定執行緒池,避免設定過大或者過小導致系統異常。

6 總結

  Dubbo 出生於阿里系,是阿里巴巴服務化治理的核心框架,並被廣泛應用於中國各網際網路公司;只需要通過 Spring 配置的方式即可完成服務化,對於應用無入侵。設計的目的還是服務於自身的業務為主。雖然阿里內部原因 Dubbo 曾經一度暫停維護版本,但是框架本身的成熟度以及文件的完善程度,完全能滿足各大網際網路公司的業務需求。如果我們需要使用配置中心、分散式跟蹤這些內容都需要自己去整合,這樣無形中增加了使用 Dubbo 的難度。

  Spring Cloud 是大名鼎鼎的 Spring 家族的產品, 專注於企業級開源框架的研發。 Spring Cloud 自從發展到現在,仍然在不斷的高速發展,幾乎考慮了服務治理的方方面面,開發起來非常的便利和簡單。

  Dubbo 於 2017 年開始又重啟維護,釋出了更新後的 2.5.6 版本,而 Spring Cloud 更新的非常快,目前已經更新到 Finchley.M2。因此,企業需要根據自身的研發水平和所處階段選擇合適的架構來解決業務問題,不管是 Dubbo 還是 Spring Cloud 都是實現微服務有效的工具。

相關文章