Alibaba-技術專區-Dubbo3總體技術體系介紹及技術指南(序章)
- 2021 年 8 月 14 日
- 筆記
- Alibaba技術專區
Dubbo的背景介紹
Apache Dubbo 是一款微服務開發框架(是一款高性能、輕量級的開源 Java 服務框架),它提供了 RPC通訊 與 微服務治理 兩大關鍵能力。這意味著,使用 Dubbo 開發的微服務,將具備相互之間的遠程發現與通訊能力, 同時利用 Dubbo 提供的豐富服務治理能力,可以實現諸如服務發現、負載均衡、流量調度等服務治理訴求。同時 Dubbo 是高度可擴展的,用戶幾乎可以在任意功能點去訂製自己的實現,以改變框架的默認行為來滿足自己的業務需求。
Dubbo的功能特性
-
面向介面代理的高性能RPC調用;
-
服務自動註冊與發現;
-
智慧負載均衡策略;
-
高度可擴展能力;
-
運行期流量調度;
-
可視化的服務治理與運維;
Dubbo的框架結構
Dubbo的發展歷程
-
2011/10/27: 阿里巴巴巴宣布 Dubbo 開源。
-
2012/10/23: 發布最後一個版本 2.5.3 並停止維護更新。
-
2017/07/31: 起死回生,官方宣布開啟重新更新,並會得到重點維護,參考:Dubbo 宣布重新開始維護。
-
2017/09/07: 發布起死回生的第一個版本:dubbo-2.5.4。
-
2018/01/08:
-
Dubbo 團隊透露 Dubbo 3.0 宣布正式開工,參考:重大利好,Dubbo 3.0要來了。
-
發布了 dubbo-2.6.0 版本,主要合併了由噹噹網開源的 dubbox 項目分支。PS:dubbo停止維護期間,噹噹網基於 dubbo 開源了dubbox。
-
-
2018/01/22: Dubbo Spring Boot 版正式發布:dubbo-spring-boot-starter v1.0.0 公測版。
-
2018/02/09: Dubbo 通過投票正式進入 Apache 基金會孵化器,更新了 Apache 官方域名,也不再僅限於 Java 語言。
-
2019/05/20: Apache 軟體基金會宣布 Dubbo 正式畢業,成為 Apache 的頂級項目。
Dubbo3.0誕生歸來
Dubbo3 基於 Dubbo2 演進而來,在保持原有核心功能特性的同時, Dubbo3 在易用性、超大規模微服務實踐、雲原生基礎設施適配等幾大方向上進行了全面升級。 以下文檔都將基於 Dubbo3 展開。
Dubbo3.0擴展延伸
從功能上看,Dubbo3.完成後的功能將涵蓋從開發人員直接接觸的 API 層到底層傳輸的完整鏈路。
-
API層將包括基於IDL的完整數據交換格式打通,這會帶來兩方面的好處:
-
一是統一的 IDL 模型可以生成統一的 client stub 和 server stub,這些 stub 能直接進行非反射調用,會在性能上有很大的提升;
-
二是對非同步和 streaming 的原生支援能夠給用戶更多的選項,根據不同的業務場景選擇更方便的用法。
-
-
第二層是對於註冊中心、元數據中心和配置中心的擴展。
- 註冊中心和配置中心基本支援了所有業界主流的實現,元數據中心是 Dubbo 2.7 新抽象出的組件,負責元數據的存取。這裡的元數據包括服務的調用配置,如超時時間,序列化方式,協議等,以及對服務方法簽名的抽象,方便 Dubbo 實現跨框架和跨語言調用。
-
集群層是Dubbo的一個主要亮點,除了支援各種重試策略外,Dubbo 也提供了各種場景下的負載均衡器,比如隨機和權重。值得一提的是,Dubbo3.0 將帶來 pull-based 的自適應負載均衡,這將顯著提升分散式集群的性能和效率。
-
再下一層是協議層,協議層是 RPC 框架的內核部分,一般分為應用層協議和傳輸層協議。應用層協議 Dubbo3.0 支援 GRPC / Redis / REST 等主流協議以及 Dubbo 原生的 Dubbo2.0 協議。
-
傳輸層支援 HTTP / HTTP2 和一些自定義的協議如 RSOCKET。序列化方面,Dubbo 除了支援 hessian 、Java 外,還支援 protobuf,這對於性能和跨語言都有著巨大的意義。
Maven 依賴
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>3.0.0</version>
</dependency>
-
Dubbo3 是在雲原生背景下誕生的,使用Dubbo構建的微服務遵循雲原生思想,能更好的復用底層雲原生基礎設施、貼合雲原生微服務架構。
-
Dubbo 3.0.0 幾乎兼容 2.7.x 所有行為。 因為,Dubbo3 是基於 Dubbo2 演進而來,在保持原有核心功能特性的同時, Dubbo3 在易用性、超大規模微服務實踐、雲原生基礎設施適配等幾大方向上進行了全面升級。
Dubbo3官方文檔
Dubbo3核心功能
- 應用級服務發現機制;
- 同時 Dubbo 3.0.0 改變以前的介面級服務註冊而是採用應用級服務註冊,什麼意思呢?比如在3.0.0版本前所有的服務都是以介面形式的元數據進行註冊如下元數據:
dubbo://192.168.101.8:20880/com.example.demo.async.api.BookFacade?anyhost=true&application=demo-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.example.demo.async.api.BookFacade&metadata-type=remote&methods=queryByName,queryAll&pid=53639&release=3.0.0&side=provider×tamp=1624889509797
- 可以看到如果我們以介面級進行服務註冊會存在大量的重複數據,這樣就會導致註冊中心數據與介面數量成正比,介面越多註冊的元數據就越多。而如果我們以應用級服務註冊會是怎樣的?下面是應用級服務註冊的共享元數據:
{ "name": "demo-provider", "id": "192.168.101.8:20880", "address": "192.168.101.8", "port": 20880, "sslPort": null, "payload": { "@class": "org.apache.dubbo.registry.zookeeper.ZookeeperInstance", "id": null, "name": "demo-provider", "metadata": { "anyhost": "true", "application": "demo-provider", "deprecated": "false", "dubbo": "2.0.2", "dubbo.endpoints": "[{\"port\":20880,\"protocol\":\"dubbo\"}]", "dubbo.metadata-service.url-params": "{\"version\":\"1.0.0\",\"dubbo\":\"2.0.2\",\"release\":\"3.0.0\",\"port\":\"20880\",\"protocol\":\"dubbo\"}", "dubbo.metadata.revision": "525892dddd25ea459ee539d0734b2f1a", "dubbo.metadata.storage-type": "remote", "dynamic": "true", "generic": "false", "interface": "com.example.demo.async.api.BookFacade",//多個服務介面只保存一個 "metadata-type": "remote", "methods": "queryByName,queryAll", "pid": "63941", "release": "3.0.0", "side": "provider", "timestamp": "1624891074206" } }, "registrationTimeUTC": 1624891075236, "serviceType": "DYNAMIC", "uriSpec": null }
-
從這些共享元數據可以看出應用級註冊減少了大量重複的元數據,能最大幅度的減輕註冊中心的存儲、推送壓力,進而減少 Dubbo 消費端的地址計算壓力。集群規模也開始變得可預測、可評估(與 RPC 介面數量無關,只與實例部署規模相關)。
-
Dubbo3之前註冊發現都是介面級別的。也就是同一個應用發布的多個服務會在註冊中心註冊多份數據,這些數據彼此獨立,方便進行服務化改造和介面遷移。為什麼要提出應用級註冊發現呢?
-
主要有兩個原因:
-
一是現有生態系統的互通,包括 Spring cloud 和 K8s 都是基於實例,也就是應用級別進行的註冊發現,Dubbo 要成為連接異構系統最好用的 RPC 框架就需要支援實例粒度;
-
二是從規模上看,更大規模的增長會帶來元數據的極速膨脹,這會給註冊中心和客戶端帶來更大的記憶體佔用。按照現有數據分析,如果升級到應用級註冊發現,以平均發布 50 個服務的應用為例,將減少 60% 的記憶體佔用和註冊中心數據。以發布超過 10k 介面的平台型應用為例,這些數據可降低 90%。
-
-
-
如何保證平滑遷移,用戶基於介面的配置怎麼映射到應用上去。
-
抽象出了元數據中心來管理介面到應用的映射以及應用級的元數據。
- 在部署態,Dubbo 框架會自動上報這個關係到元數據中心。
- 運行態用戶側的配置和服務治理則通過這份映射關係重新將應用粒度映射到介面粒度。涉及到最核心的部分——選址也是分為兩部分,應用級選址和介面級選址同時存在,方便進行服務治理。應用級註冊發現帶來的優化是十分顯著的。
-
下一代RPC協議:Triple:Triple 協議是 Dubbo3 的主力協議,完整兼容 gRPC over HTTP/2,並在協議層面擴展了負載均衡和流量控制相關機制。
-
全新的路由規則;
-
顯著提升性能;
-
Kubernetes 服務集成:
-
Dubbo3主要在雲服務能力上做了新的能力提升。為什麼這麼說呢?因為作者之前在工作中集成 Kubernetes 時候服務註冊中心這個組件能力就非常的尷尬,因為 Kubernetes 本身就提供了服務註冊與發現能力,但是不能和 Dubbo 完美整合起來。
-
Dubbo3之前我們的實現方式可能就是在Kubernetes部署一個 zookeeper 服務集群來進行服務註冊與發現。但這樣的實現方式在雲服務應用來說並不是太合適,這種服務註冊和發現能力交給基礎服務組件來實現比較合適。
-
- 一是需要對齊 K8s 的生命周期,能夠讓 Dubbo 服務原生的在 K8s 體系內註冊和發現;
- 二是對 Mesh 的支援。上面在協議那裡我們已經講到,新協議通過使用 HTTP2 進行 header / payload 分離解決了網關需要解析完整協議的問題。另外一個問題則是服務註冊發現和治理,註冊發現需要 Dubbo 能夠在 Mesh 的 xDS 體系內作為數據面打通。治理則需要將原有的規則逐步遷移至基於 YAML 的剔除 IP 依賴的規則。最終的形態將是原生的 Dubbo 服務能夠和基於 thin SDK 的 Dubbo + Mesh 完美互通和進行服務治理。
Dubbo3.0原生微服務
承接上面對K8s整合之後,Dubbo3.0 -下一代雲原生微服務。
一個新架構或新技術的出現一定會伴隨特定的發展趨勢。
目前我們可以看到的幾個趨勢是 K8s 成為資源調度的事實標準、Mesh 化成為主流以及規模上的急速增長。這些趨勢的存在對 Dubbo 提出了更高的要求:
- 首先,用戶如何在 K8s 上更方便的部署和調用 Dubbo 服務是必須要解決的問題,要解決這個問題,統一的協議和數據交換格式是必須前提;
- 其次,Mesh 化的流行帶來了多元化問題,即原生 Dubbo 和 Mesh 化 Dubbo 如何共存,多語言的場景如何支援;
- 第三點,規模的增長會給整個 Dubbo 架構帶來更大的挑戰,無論是註冊中心等組件,還是客戶端,都會有更多的數據和調用量。如何在保持穩定的前提下,提供更高效的服務是 Dubbo 演進的重中之重。
- 這些雲原生時代帶來的挑戰,促成了 Dubbo 的下一代定義。新協議、K8s 基礎架構支援、多語言支援和規模化支援四個子項目共同組成了 Dubbo3.0 。下面我們將走進 Dubbo3.0,看看具體有哪些新特性。
Dubbo3擴展分離
Dubbo 核心不再提供第三方 SDK 擴展,需要通過 dubbo-spi-extensions 項目來支援。
Dubbo3多樣化註冊
-
Zookeeper 作為註冊中心、元數據報告、配置中心;
-
Nacos 作為註冊中心、元數據報告、配置中心;
-
Kubernetes 作為註冊中心;
-
Redis 作為元數據報告;
-
Apollo 作為配置中心;
-
Hessian2 和 jdk 作為默認序列化器;
-
Triple 協議支援 Protobuf;
Dubbo3的升級提醒
-
基於 Spring 的相關配置列表可能會發生變更,請留言官方升級文檔;
-
為了高度兼容性,Dubbo 3 早期版本會默認開啟多重註冊,多重訂閱;
Dubbo3.0柔性增強
柔性增強要解決的問題有兩個:
- 一是在節點異常的情況下,分散式服務能夠保持穩定,不出現雪崩等問題;
- 二是對於大規模的應用,能夠以最佳態運行,提供較高的吞吐量和性能。
從方法上看,Dubbo3.0 的柔性增強會以面向失敗設計為理念,提供包括精準容量評估、自適應限流、自適應負載均衡的支援,自底向上的分步構建大規模可靠應用。從單一服務的視角看,服務是壓不垮的,穩定的。
從分散式視角看,複雜的拓撲不會帶來性能的下降,分散式負載均衡能夠以最優的方式動態分配流量,保證異構系統能夠根據運行時的準確服務容量合理分配請求,從而達到性能最優。
Dubbo3代表下一代RPC協議
Dubbo2.x的協議報文頭
大家可以看到,這是 Dubbo2.0 的協議。從功能上看, Dubbo2.0 提供了 RPC 的核心語義,包括協議頭、標誌位、請求 ID 以及請求/響應數據。在雲原生時代,2.0 協議主要面臨兩個挑戰:
-
一是生態不互通,用戶很難直接理解二進位的協議;
-
二是對 Mesh 等網關型組件不夠友好,需要完整的解析協議才能獲取到所需要的調用元數據,如一些 RPC 上下文,從性能到易用性方面都會面臨挑戰。
Dubbo3的協議報文頭
-
首先,協議需要解決跨語言互通的問題,傳統的多語言多 SDK 模式和 Mesh 化跨語言模式都需要一種更通用易擴展的數據傳輸格式;
-
其次,協議應該提供更完善的請求模型,除了 Request/Response 模型,還應該支援 Streaming 和 Bidirectional;
-
再次,在性能上,新的協議應該保留 request Id 機制,以避免 HOL 帶來的性能損耗;
-
最後,新協議應該易擴展,包括但不限於 Tracing/ Monitoring 等支援,也應該能被各層設備識別,降低用戶理解難度。
-
基於這些需求,HTTP2/protobuf 的組合是最符合的。提到這兩個,大家可能很容易想到 GRPC 協議。那新一代的協議和 GRPC 的關係是什麼呢?
-
首先,Dubbo 新協議是基於 GRPC 擴展的協議,這也保證了在生態系統上新協議和 GRPC 是能夠互通和共享的;
-
其次,在這個基礎上,Dubbo 新協議將更原生地支援 Dubbo 的服務治理,提供更大的靈活性;
-
在序列化方面,由於目前大多數應用方還沒有使用 Protobuf ,所以新協議會在序列化方面給予足夠的支援,平滑的適配現有序列化,方便遷移到 Protobuf;
-
在請求模型上,新協議將原生支援 Reactive,這也是 GRPC 協議所不具備的。