【微服務】:Java 微服務框架選型(Dubbo 和 Spring Cloud)

引言

微服務(Microservices)是一種架構風格,一個大型複雜軟件應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每個微服務僅關注於完成一件任務並很好地完成該任務。在所有情況下,每個任務代表着一個小的業務能力。

以往我們開發應用程序都是單體型,雖然開發和部署比較方便,但後期隨着業務的不斷增加,開發迭代和性能瓶頸等問題,將會困擾開發團隊,微服務就是解決此問題的有效手段,市面上有很多的微服務框架,比如最著名的兩個 Dubbo 和 Spring Cloud,我們該如何選擇呢?

1. 關於 RPC/gRPC/HTTP/REST

因爲服務調用方式是 Dubbo 和 Spring Cloud 重要不同點,瞭解 RPC/gRPC/HTTP/REST 相關概念,有助於對比 Dubbo 和 Spring Cloud。

HTTP 嚴格來說跟 RPC 不是一個層級的概念,HTTP 本身也可以作爲 RPC 的傳輸層協議。

傳輸協議包含: 如著名的 gRPC 使用的 HTTP 2.0 協議,也有如 Dubbo 一類的自定義報文的 TCP 協議。編碼協議包含: 如基於文本編碼的 XML Json,也有二進制編碼的 ProtoBuf Binpack 等。

所謂的效率優勢是針對 HTTP 1.1 協議來講的,HTTP 2.0 協議已經優化編碼效率問題,像 gRPC 這種 RPC 庫使用的就是 HTTP 2.0 協議。

在跨語言調用的時候,REST 風格直接把 HTTP 作爲應用協議(直接和服務打交道),不同語言之間調用比較方便。

而 RPC 可以把 HTTP 作爲一種傳輸協議(比如 gRPC 使用 HTTP 2.0 協議傳輸),本身還會封裝一層 RPC 框架的應用層協議,不同語言之間調用需要依賴 RPC 協議(需要跨語言 RPC 庫實現,比如 Thrift)。

問題:爲什麼 Dubbo 比 Spring Cloud 性能要高一些?

回答:因爲 Dubbo 採用單一長連接和 NIO 異步通訊(保持連接/輪詢處理),使用自定義報文的 TCP 協議,並且序列化使用定製 Hessian2 框架,適合於小數據量大併發的服務調用,以及服務消費者機器數遠大於服務提供者機器數的情況,但不適用於傳輸大數據的服務調用。而 Spring Cloud 直接使用 HTTP 協議(但也不是強綁定,也可以使用 RPC 庫,或者採用 HTTP 2.0 + 長鏈接方式(Fegin 可以靈活設置))。

另外,Martin Fowler 的 MicroServices 一文,其定義的服務間通信是 HTTP 協議的 REST API。

2. Dubbo

Github:https://github.com/apache/incubator-dubbo

Dubbo 是一個分佈式服務框架,致力於提供高性能和透明化的 RPC 遠程服務調用方案,以及 SOA 服務治理方案。簡單的說,Dubbo 就是個服務框架,說白了就是個遠程服務調用的分佈式框架。

2.1. Dubbo 框架

在這裏插入圖片描述

模塊註解:

  • Provider: 暴露服務的服務提供方。
  • Consumer: 調用遠程服務的服務消費方。
  • Registry: 服務註冊與發現的註冊中心。
  • Monitor: 統計服務的調用次調和調用時間的監控中心。
  • Container: 服務運行容器。

流程詳解:

  • 0 服務容器負責啓動,加載,運行服務提供者(Standalone 容器)。
  • 1 服務提供者在啓動時,向註冊中心註冊自己提供的服務(Zookeeper/Redis)。
  • 2 服務消費者在啓動時,向註冊中心訂閱自己所需的服務。
  • 3 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連接推送變更數據給消費者。
  • 4 服務消費者,從提供者地址列表中,基於軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
  • 5 服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘發送一次統計數據到監控中心(根據數據可以動態調整權重)。

2.2. Dubbo 集羣容錯

在這裏插入圖片描述

面對服務消費方,當業務邏輯中需要調用一個服務時,真正調用的其實是 Dubbo 創建的一個 Proxy,該 Proxy 會把調用轉化成調用指定的 Invoker(Cluster 將 Directory 中的多個 Invoker 僞裝成一個 Invoker,對上層透明,僞裝過程包含了容錯邏輯,調用失敗後,重試另一個(通過 LoadBalance),Invoker 封裝了 Provider 地址及 Service 接口信息)。而在這一系列的委託調用的過程裏就完成了服務治理的邏輯,最終完成調用。

2.3. Dubbo 特點

  • 遠程通訊: 提供對多種基於長連接的 NIO 框架抽象封裝(非阻塞 I/O 的通信方式,Mina/Netty/Grizzly),包括多種線程模型,序列化(Hessian2/ProtoBuf),以及“請求-響應”模式的信息交換方式。
  • 集羣容錯: 提供基於接口方法的透明遠程過程調用(RPC),包括多協議支持(自定義 RPC 協議),以及軟負載均衡(Random/RoundRobin),失敗容錯(Failover/Failback),地址路由,動態配置等集羣支持。
  • 自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。

2.4. Dubbo 發展歷程

  • 2008 年,阿里巴巴開始內部使用 Dubbo。
  • 2009 年初,發佈 1.0 版本。
  • 2010 年初,發佈 2.0 版本。
  • 2011 年 10 月,阿里巴巴宣佈開源,版本爲 2.0.7。
  • 2012 年 3 月,發佈 2.1.0 版本。
  • 2013 年 3 月,發佈 2.4.10 版本。
  • 2014 年 10 月,發佈 2.3.11 版本,之後版本停滯。
  • 2017 年 9 月,阿里巴巴重啓維護,重點升級所依賴 JDK 及組件版本,發佈 2.5.4/5 版本。
  • 2017 年 10 月,發佈 2.5.6 版本。
  • 2017 年 11 月,發佈 2.5.7 版本,後期集成 Spring Boot。
  • 2014 年 10 月,噹噹網 Fork 了 Dubbo 版本,命名爲 Dubbox-2.8.0,並支持 HTTP REST 協議。

Dubbo 負責人說明(重啓維護是接受的採訪):

阿里內部使用 HSF,原因業務屬性和規模有關。
這裏就不得不提到目前的一些文章在談到微服務的時候總是拿 Spring Cloud 和 Dubbo 來對比,需要強調的是 Dubbo 未來的定位並不是要成爲一個微服務的全面解決方案,而是專注在 RPC 領域,成爲微服務生態體系中的一個重要組件。至於大家關注的微服務化衍生出的服務治理需求,我們會在 Dubbo 積極適配開源解決方案,甚至啓動獨立的開源項目予以支持。
受衆主要來自國內各友商以及個人開發者,希望將來能夠將用戶拓展到全球,代表國人在 RPC 領域與 gRPC(基於 HTTP 2.0)、Finagle 等競爭。

3. Spring Cloud

Github: https://github.com/spring-cloud

Spring Cloud 基於 Spring Boot,爲微服務體系開發中的架構問題,提供了一整套的解決方案——服務註冊與發現,服務消費,服務保護與熔斷,網關,分佈式調用追蹤,分佈式配置管理等。

重點:

  • 基於 Spring Boot
  • 雲服務、分佈式框架集合(衆多)

核心功能:

  • 分佈式/版本化配置
  • 服務註冊和發現
  • 路由
  • 服務和服務之間的調用
  • 負載均衡
  • 斷路器
  • 分佈式消息傳遞

3.1. Spring Cloud 完整技術

在這裏插入圖片描述

3.2. Spring Cloud 組件架構

在這裏插入圖片描述

流程:

  • 請求統一通過 API 網關(Zuul)來訪問內部服務。
  • 網關接收到請求後,從註冊中心(Eureka)獲取可用服務。
  • 由 Ribbon 進行均衡負載後,分發到後端具體實例。
  • 微服務之間通過 Feign 進行通信處理業務。
  • Hystrix 負責處理服務超時熔斷。
  • Turbine 監控服務間的調用和熔斷相關指標。

3.3. Spring Cloud工具框架

  • Spring Cloud Config 配置中心,利用 Git 集中管理程序的配置。
  • Spring Cloud Netflix 集成衆多Netflix的開源軟件。
  • Spring Cloud Netflix Eureka 服務中心(類似於管家的概念,需要什麼直接從這裏取,就可以了),一個基於 REST 的服務,用於定位服務,以實現雲端中間層服務發現和故障轉移。
  • Spring Cloud Netflix Hystrix 熔斷器,容錯管理工具,旨在通過熔斷機制控制服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。
  • Spring Cloud Netflix Zuul 網關,是在雲平臺上提供動態路由,監控,彈性,安全等邊緣服務的框架。Web 網站後端所有請求的前門。
  • Spring Cloud Netflix Archaius 配置管理 API,包含一系列配置管理API,提供動態類型化屬性、線程安全配置操作、輪詢框架、回調機制等功能。
  • Spring Cloud Netflix Ribbon 負載均衡。
  • Spring Cloud Netflix Fegin REST客戶端。
  • Spring Cloud Bus 消息總線,利用分佈式消息將服務和服務實例連接在一起,用於在一個集羣中傳播狀態的變化。
  • Spring Cloud for Cloud Foundry 利用 Pivotal Cloudfoundry 集成你的應用程序。
  • Spring Cloud Cloud Foundry Service Broker 爲建立管理雲託管服務的服務代理提供了一個起點。
  • Spring Cloud Cluster 集羣工具,基於 Zookeeper, Redis, Hazelcast, Consul 實現的領導選舉和平民狀態模式的抽象和實現。
  • Spring Cloud Consul 基於 Hashicorp Consul 實現的服務發現和配置管理。
  • Spring Cloud Security 安全控制,在 Zuul 代理中爲 OAuth2 REST 客戶端和認證頭轉發提供負載均衡。
  • Spring Cloud Sleuth 分佈式鏈路監控,SpringCloud 應用的分佈式追蹤系統,和 Zipkin,HTrace,ELK 兼容。
  • Spring Cloud Data Flow 一個雲本地程序和操作模型,組成數據微服務在一個結構化的平臺上。
  • Spring Cloud Stream 消息組件,基於 Redis,Rabbit,Kafka 實現的消息微服務,簡單聲明模型用以在 Spring Cloud 應用中收發消息。
  • Spring Cloud Stream App Starters 基於 Spring Boot 爲外部系統提供 Spring 的集成。
  • Spring Cloud Task 短生命週期的微服務,爲 Spring Booot 應用簡單聲明添加功能和非功能特性。
  • Spring Cloud Task App Starters。
  • Spring Cloud Zookeeper 服務發現和配置管理基於 Apache Zookeeper。
  • Spring Cloud for Amazon Web Services 快速和亞馬遜網絡服務集成。
  • Spring Cloud Connectors 便於PaaS應用在各種平臺上連接到後端像數據庫和消息經紀服務。
  • Spring Cloud Starters (項目已經終止並且在 Angel.SR2 後的版本和其他項目合併)
  • Spring Cloud CLI 命令行工具,插件用 Groovy 快速的創建 Spring Cloud 組件應用。

4. Dubbo的優缺點

優點

  • Dubbo 支持 RPC 調用,服務之間的調用性能會很好。
  • 支持多種序列化協議,如 Hessian、HTTP、WebService。
  • Dobbo Admin後臺管理功能強大,提供了路由規則、動態配置、訪問控制、權重調節、均衡負載等功能。
  • 在國內影響力比較大,中文社區文檔較爲全面。
  • 阿里最近重啓維護。

缺點

  • Registry 嚴重依賴第三方組件(zookeeper 或者 redis),當這些組件出現問題時,服務調用很快就會中斷。
  • Dubbo 只支持 RPC 調用。使得服務提供方(抽象接口)與調用方在代碼上產生了強依賴,服務提供者需要不斷將包含抽象接口的 jar 包打包出來供消費者使用。一旦打包出現問題,就會導致服務調用出錯,並且以後發佈部署會成很大問題(太強的依賴關係)。
  • 另外,以後要兼容 .NET Core 服務,Dubbo RPC 本身不支持跨語言(可以用跨語言 RPC 框架解決,比如 Thrift、gRPC(重複封裝了),或者自己再包一層 REST 服務,提供跨平臺的服務調用實現,但相對麻煩很多)
  • Dubbo 只是實現了服務治理,其他微服務框架並未包含,如果需要使用,需要結合第三方框架實現(比如分佈式配置用淘寶的 Diamond、服務跟蹤用京東的 Hydra,但使用相對麻煩些),開發成本較高,且風險較大。
  • 社區更新不及時(雖然最近在瘋狂更新),但也難免阿里以後又不更新了,就尷尬了。
  • 主要是國內公司使用,但阿里內部使用 HSF,相對於 Spring Cloud,企業應用會差一些。

5. Spring Cloud的優缺點

優點

  • 有強大的 Spring 社區、Netflix 等公司支持,並且開源社區貢獻非常活躍。
  • 標準化的將微服務的成熟產品和框架結合一起,Spring Cloud 提供整套的微服務解決方案,開發成本較低,且風險較小。
  • 基於 Spring Boot,具有簡單配置、快速開發、輕鬆部署、方便測試的特點。
  • 支持 REST 服務調用,相比於 RPC,更加輕量化和靈活(服務之間只依賴一紙契約,不存在代碼級別的強依賴),有利於跨語言服務的實現,以及服務的發佈部署。另外,結合 Swagger,也使得服務的文檔一體化。
  • 提供了 Docker 及 Kubernetes 微服務編排支持。
  • 國內外企業應用非常多,經受了大公司的應用考驗(比如 Netfilx 公司),以及強大的開源社區支持。

缺點

  • 支持 REST 服務調用,可能因爲接口定義過輕,導致定義文檔與實際實現不一致導致服務集成時的問題(可以使用統一文檔和版本管理解決,比如 Swagger)。
  • 另外,REST 服務調用性能會比 RPC 低一些(但也不是強綁定)
  • Spring Cloud 整合了大量組件,相關文檔比較複雜,需要針對性的進行閱讀。

6. Dubbo 和 Spring Cloud 對比

在這裏插入圖片描述
Dubbo 專注 RPC 和服務治理,Spring Cloud 則是一個微服務架構生態。

6.1. 服務調用方式的不同

Spring Cloud 拋棄了 Dubbo 的 RPC 通信,採用的是基於 HTTP 的 REST 方式。嚴格來說,這兩種方式各有優劣。雖然從一定程度上來說,後者犧牲了服務調用的性能,但也避免了上面提到的原生 RPC 帶來的問題。而且 REST 相比 RPC 更爲靈活,服務提供方和調用方的依賴只依靠一紙契約,不存在代碼級別的強依賴,這在強調快速演化的微服務環境下,顯得更加合適。

6.2. ZooKeeper 和 Eureka 的區別

鑑於服務發現對服務化架構的重要性,Dubbo 實踐通常以 ZooKeeper 爲註冊中心(Dubbo 原生支持的 Redis 方案需要服務器時間同步,且性能消耗過大)。針對分佈式領域著名的 CAP 理論(C——數據一致性,A——服務可用性,P——服務對網絡分區故障的容錯性),Zookeeper 保證的是 CP ,但對於服務發現而言,可用性比數據一致性更加重要,AP 勝過 CP,而 Eureka 設計則遵循 AP 原則。

Spring Cloud 支持 Consul(CA)和 Zookeeper,但不推薦使用。

7. Dubbo 和 Spring Cloud 比喻

使用 Dubbo 構建的微服務架構就像組裝電腦,各環節我們的選擇自由度很高,但是最終結果很有可能因爲一條內存質量不行就點不亮了,總是讓人不怎麼放心,但是如果你是一名高手,那這些都不是問題;而 Spring Cloud 就像品牌機,在 Spring Source 的整合下,做了大量的兼容性測試,保證了機器擁有更高的穩定性,但是如果要在使用非原裝組件外的東西,就需要對其基礎有足夠的瞭解。

總結

關於 Dubbo 和 Spring Cloud 的相關概念和對比,上面已經敘述的很清楚了,我個人比較傾向於 Spring Cloud,原因就是真正的微服務框架、提供整套的組件支持、使用簡單方便、強大的社區支持等等,另外,因爲考慮到 .NET/.NET Core 的兼容處理,RPC 並不能很好的實現跨語言(需要藉助跨語言庫,比如 gRPC、Thrift,但因爲 Dubbo 本身就是“gRPC”,在 Dubbo 之上再包一層 gRPC,有點重複封裝了),而 HTTP REST 本身就是支持跨語言實現,所以,Spring Cloud 這一點還是非常好的(Dubbox 也支持,但性能相比要差一些)。

但凡事無絕對,每件事物有好的地方也有不好的地方,總的來說,Dubbo 和 Spring Cloud 的主要不同體現在兩個方面:服務調用方式不同和專注點不同(生態不同)。

最後,關於 Service Mesh,因爲是很新的概念(去年年底才火起來),相關的框架並未真正用於生產環境,所以這邊就不考慮了,但以後可能會發展的非常好。

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