dubbogo 3.0:牽手 gRPC 走向雲原生時代

自從 2011 年 Dubbo 開源以後,被大量中小公司採用,一直是國內最受歡迎的 RPC 框架。2014年 因爲阿里內部組織架構調整,Dubbo 暫停維護了一段時間,以後隨着 Spring Cloud 的面世,兩個體系在融合中一塊兒助推了微服務的火熱。docker

不過這世界變化快,自從以 docker 爲表明的的容器技術和以 k8s 爲表明的容器編排技術登上舞臺以後,雲原生時代到來了。在雲原生時代,不可變的基礎設施給原有的中間件帶來的了不可變的中間件基礎設施:gRPC 統一了底層通訊層,protobuf 統一了序列化協議,以 envoy + istio 爲表明的 service mesh 逐漸統一了服務的控制面與數據面。編程

dubbogo 的自然使命是:Bridging the gap between Java and Go。保持 Go 應用與 Java 應用互聯互通的同時,藉助 Go 語言(事實上的遠程桌面第一雲原生語言)的優點擁抱雲原生時代。dubbogo 社區 2020 年勠力打造三支箭:已經發布的對齊 dubbo 2.7 的 dubbogo v1.5 版本、近期將要發佈的 sidecar 形態的 dubbo-go-proxy 項目 以及 處於進行時的 dubbogo 3.0。網絡

用一句話歸納 dubbogo 3.0 便是:新通訊協議、新序列化協議、新應用註冊模型以及新的服務治理能力!本文主要着重討論 dubbogo 3.0 的新通訊協議和應用級服務註冊發現模型。架構

  1. dubbogo 3.0 vs gRPC

知己知彼,方能進步。dubbogo 3.0 的通訊層改進主要借鑑了 gRPC。app

簡單來講就是http2協議的基礎之上,增長了特定的協議header:「grpc-」開頭的header字段,採用特定的打解包工具(protobuf)對數據進行序列化,從而實現RPC調用。
衆所周知,gRPC 幾乎沒有服務治理能力,而阿里雲現有 dubbo 框架兼具 RPC 和服務治理能力,總體實力不遜於 gRPC。但「你們都用gRPC」 這樣的背景之下,dubbogo 3.0 的新通訊協議就必須完美兼容 gRPC,對開發者已部署的服務徹底兼容,並在此基礎之上延續已有 dubbo 協議和服務治理能力,進而推出一系列新策略:好比mesh支持、應用級服務註冊等。框架

  1. dubbogo 3.0 vs dubbogo 1.5

目前已有的 dubbo 2.7 協議已經儘量實現了 gRPC 的支持。開發者能夠經過 protoc-gen-dubbo 工具將 pb IDL 協議轉換爲框架支持的 stub,再借助底層 gRPC conn 的 RPC 過程,將已有的服務治理能力自上而下傳遞給了 gRPC,所以實現了 gRPC 服務的支持。運維

dubbo-go v1.5.x 也支持 gRPC 的 Stream 調用。和 unary RPC 相似,經過產生框架支持的 stub,在底層gRPC stream 調用的基礎之上,將流式 RPC 的能力和併入框架。但因爲 dubbo v2.7.x / dubbo-go v1.5.x 自己並不支持流式調用,因此沒有對 gRPC stream 調用的進行上層服務治理支持。異步

開發者所面臨的問題就是:咱們在使用dubbo-go2.7進行grpc協議傳輸的時候,或多或少不是那麼放心。編程語言

而即將推出的 dubbo-go 3.0 協議將從根源解決這個問題。ide

  1. 協議兼容的三種層次

筆者認爲,一款服務框架對於第三方協議的支持可分爲三個程度:應用層次、協議層次、傳輸層次。

一款框架若是在一個協議的 sdk 之上封裝接口,能夠認爲它處於應用層次支持,這樣的框架須要遵循下層 sdk 的接口,可擴展性較差。

處於協議層次的框架,從配置層到服務治理層均由本框架提供,而在此之下的協議層到網絡傳輸層均使用某個固定的通訊協議,這樣的框架能夠解決服務治理的問題,但框架自己沒法與第三方協議徹底適配,若是不適配就會出現對第三方協議支持的削弱,好比上面說到的 dubbo-go 1.5 對 stream rpc 支持的缺陷。

若是想進一步支持更多的第三方協議,須要從傳輸層下手,真正瞭解第三方協議的具體字段、所依賴的底層協議(好比 HTTP2)的幀模型和數據流,再開發出與第三方協議徹底一致的數據交互模塊,做爲本框架的底層。這樣作的好處是最大程度賦予了協議的可擴展性,能夠在兼容已有協議的基礎之上,可選地增長開發者須要的字段,從而實現已有協議沒法實現的功能,就好比 dubbogo 3.0 將支持的反壓策略。

  1. 基於 HTTP2 的通訊流程

gRPC 一次基於 HTTP2 的 unary rpc 調用傳輸主要流程以下:

client 發送 Magic 信息 PRI * HTTP/2.0rnrnSMrnrn

server 收到並檢查是否正確

client 和 server 互相發送 setting 幀,收到後發送ACK 確認

client 發送 Header 幀,包含 gRPC 協議字段,以 End Headers 做爲 Header 結束標誌

client 緊接着發送 Data 幀,包含 RPC 調用的 request 信息,以 End Stream 做爲 Data 結束標誌

server 調用函數得到結果

server 發送 Header 幀,包含 gRPC 協議字段,以 End Headers 做爲 Header 結束標誌

server 緊接着發送Data幀,包含 RPC 調用回傳的 response 信息

server 緊接着再次發送 Header 幀,包含 RPC 狀態和 message 信息,以 End Stream 做爲本次 RPC 調用結束標誌

另外,在 gRPC 的 stream 調用中,可在 server 端回傳的過程當中發送屢次 Data,調用結束後再發送 Header 終止 RPC 過程,並彙報狀態信息。

dubbogo 3.0 的通訊層將在 HTTP2 通訊協議之上採用一樣的通訊流程,以保證與 gRPC 的底層通訊溝通能力。

  1. dubbogo 3.0 預期通訊架構

除了通訊協議採用 HTTP2 外,dubbogo 3.0 將採用 基於 google protobuf 的 triple 協議【下面稱爲 dubbo3 協議】做爲 dubbogo 3.0 的序列化協議,爲 dubbo 未來支持更多的編程語言打下通訊協議層面的基礎。 目前設計的 dubbogo 3.0 傳輸模型

爲保證同時支持 unary RPC 和 stream RPC,在 server 端和 client 端增長數據流結構,以異步調用的形式完成數據傳遞。

繼續支持原有的 TCP 通訊能力

在 HTTP2 的通訊協議之上支持 dubbo3協議,decode 過程兼容 gRPC 使用的的 protobuf,保證與 gRPC 服務打通。

  1. 應用級服務註冊發現

6.1 應用級服務註冊發現介紹

dubbogo 3.0 使用的新一代服務註冊發現體系,將摒棄舊版的「接口級註冊發現」,使用「應用級別註冊發現」。

簡單地說,接口級別註冊發現,在註冊中心中以 RPC 服務爲key,以實例列表做爲 value 來組織數據的,而咱們新引入的「應用粒度的服務發現」,它以應用名(Application)做爲 key,以這個應用部署的一組實例(Instance)列表做爲 value。這帶來兩點不一樣:

數據映射關係變了,從 RPC Service -> Instance 變爲 Application -> Instance

數據變少了,註冊中心沒有了 RPC Service 及其相關配置信息

能夠認爲,基於應用粒度的模型所存儲和推送的數據量是和應用、實例數成正比的,只有當咱們的應用數增多或應用的實例數增加時,地址推送壓力纔會上漲。

而對於基於接口粒度的模型,數據量是和接口數量正相關的,鑑於一個應用一般發佈多個接口的現狀,其數量級通常是比應用粒度的數十倍。另一個關鍵點在於,接口的定義更多的是業務側的內部行爲,接口粒度致使的集羣規模評估的不透明,而實例、應用增加都一般是在運維側的規劃之中,可控性較好。

工商銀行曾經對這兩個模型進行生產測算:應用級服務註冊模型可讓註冊中心上的數據量變成原來的 1.68%,新模型可讓 zookeeper 輕鬆至成 10 萬級別的服務量和 10 萬級別的節點量。

6.2 元數據中心同步機制的引入

數據中心的數據量變少所形成的結果,是RPC 服務相關的數據在註冊中心消失了,只有 application - instance 這兩個層級的數據。爲了保證這部分缺乏的 RPC 服務數據仍然能被 Consumer 端正確的感知,咱們在 Consumer 和 Provider 間創建了一條單獨的通訊通道,目前針對元數據同步有兩種具體的可選方案,分別是:

內建 MetadataService。

獨立的元數據中心,經過中細化的元數據集羣協調數據。

相關文章
相關標籤/搜索