簡介:Dubbo-go 是常新的,每年都在不斷進化。介紹 Dubbo-go 3.0 工作之前,先回顧其過往 6 年的發展歷程,以明晰未來的方向。
作者 | 李志信
來源 | 阿里技術公眾號
作者介紹:
李志信(github @laurencelizhixin),dubbo-go 3.0 負責人,Apache Dubbo PMC,來自阿里雲中間件團隊,從事 Go 語言中間件的研發和開源工作。
於雨 (github @AlexStocks),dubbo-go 社區負責人,Apache Dubbo PMC,螞蟻集團可信原生部【TNT】基礎設施和中間件研發一線程序員。工作十一年來陸續參與和改進過 Redis/Pika/Pika-Port/etcd/Muduo/Dubbo/dubbo-go/Sentinel-golang/Seata-golang 等知名項目。
牛學蔚(github @justxuewei),Apache Dubbo Committer,北郵計算機學院二年級研究生,對中間件、雲原生領域有着濃厚的興趣。
董劍輝(github @Mulavar),Apache Dubbo Committer,目前主要關注的開源方向為 Dubbo、Flink、Calcite。
我們在今年下半年的雲計算基礎架構大會上了解到了“基礎架構能力下沉”的重大意義,從單體架構到雲原生架構的一步步發展,都在努力將業務代碼與中間件解耦,盡可能提供統一的編程接口,通過AOP的思路將服務調用抽象化,將接口標准化,將基礎設施的實現下沉化。而 Dubbo-go 正是在原有保證網絡通信的高可用、穩定性的前提下,整合了一批常用開源組件,提供一致的編程接口可供擴展和調用。在此之上,對齊 Dubbo 生態主流控制面,嘗試與雲原生結合,朝向 Proxyless Service Mesh 方向發展,是我們整個生態項目的一致的願景。
在 3.0 時代,我們的“野心” 不會止步於已有的用戶使用場景和基礎框架能力,我們選擇追求高可用、多語言、跨生態的優點,打造新一代微服務基礎設施,實現 “Bridging The Gap Between X And Go”,在擴展 Go 生態的同時,也實現各種基礎設施的雲原生化。
一 Dubbo-go 簡介
Dubbo-go 是常新的,每年都在不斷進化。介紹 Dubbo-go 3.0 工作之前,先回顧其過往 6 年的發展歷程,以明晰未來的方向。
1 什么是 Dubbo-go
github.com/apache/dubbo-go 是一款高性能 Go 語言微服務 RPC 框架,在 Dubbo 多語言生態中扮演重要角色,是編寫 go 語言微服務的最佳選擇之一。
開發者可以使用 Dubbo-go 框架高效地編寫 RPC 服務,並支持與 Dubbo、gRPC 服務跨語言互通;您可以使用 Dubbo 生態強大的服務治理能力和運維能力,例如服務注冊發現、負載均衡、配置中心、可視化等功能;您也可以使用 Dubbo-go 生態的 pixiu 網關將服務暴露給集群外部訪問。
Dubbo-go 項目由於雨於 2016 年創立,2018 年開始組建開源社區,2019 年項目正式進入 Apache 軟件基金會,經歷三年多不斷地迭代和優化,2021 年底 dubbogo 社區正式推出集成 新通信協議、新序列化協議、新應用注冊模型、新路由以及新的服務治理能力的 v3.0 版本,該版本在前期研發階段已經擁有了眾多生產用戶的關注和使用。
Dubbo-go 是阿里開源項目中最活躍的開源社區之一,多年的發展使社區積累了眾多熱愛開源的活躍貢獻者、 Apache Committer/PMC 成員。不僅給 Dubbo 以及其他 Dubbo 生態項目示范了通過社區的組織運營幫助項目發展,而且幫助了提升了整個 Dubbo 大社區的活躍度:
- 包括 Apache/Dubbo 與 Apache/Dubbo-go 在內的 Dubbo 生態被評為 2021 年中國 20 大最活躍社區之一,位居阿里所有開源項目第二【第一是螞蟻集團的 AntD】
- Dubbo-go 已經成功申報中國科學技術協會主辦的「 2021“科創中國”開源創新榜評選 」
- Dubbo-go 開源社區被 OSCHINA 評為“2021 年度 OSCHINA 優秀開源技術團隊”
2 功能介紹
Dubbo-go 目前已經達成了其初始使命 “Bridging The Gap Between Java And Go” ,具備了強大的互聯互通能力,並在雲原生方向取得了長足的進展。
- 互聯互通能力
其中 Triple 協議是 Dubbo3 生態主推的協議,是基於 gRPC 的擴展協議,底層為HTTP2,可與 gRPC 服務互通。相當於在 gRPC 可靠的傳輸基礎上,增加了 Dubbo 的服務治理能力。
Dubbo-go 生態整體已經與 Dubbo、gRPC、Spring Cloud 等生態互聯互通,把東西向和南北向數據面流量統一於一體:既可以通過 Dubbo-go 進行東西方向服務調用,也可以在 Dubbo-go-pixiu 中進行南北向流量治理。
- Devops 能力
在配置中心方面,開發者可以使用Nacos、Apollo(攜程開源)、Zookeeper 進行框架/用戶的配置的發布和拉取。
在流量控制方面,我們內置實現了固定窗口、滑動窗口等知名的限流算法,同時也支持與第三方成熟的限流熔斷框架 Hystrix,Sentinel-golang 等集成提供治理功能。
在分布式事務方面,我們支持 Seata-golang,實現了 TCC 模式分布式事務的調用。
在鏈路追蹤方面,我們支持基於 Jaeger、ZipKin 的鏈路追蹤能力。
在指標可視化方面,我們支持使用 Prometheus 收集框架指標和用戶指標。
3 目標用戶
Dubbo-go 從開始即是面向生產環境基於用戶的實際需求構建開發的,其目標用戶如下。
- 廣大 Go 語言微服務開發者
如果您是 Go 語言微服務開發者,希望基於輕量級微服務框架快速開發自己的服務,那么 Dubbo-go 3.0 將是您很好的一個選擇。
- Dubbo 生態多語言使用者
如果您是 Dubbo 生態使用者,或者在語言切換的過程中面對兼容性問題,Dubbo-go 在多協議跨語言互通的場景下會祝您一臂之力。
- gRPC 使用者
如果您希望在 gRPC 生態中增加服務治理能力,Dubbo-go 可幫助您很容易地從 gRPC 接入 Dubbo 生態,在不改變業務代碼的情況下提供服務治理能力的支持。
- 雲原生架構師
如果你在為公司選擇雲原生解決方案,dubbogo 3.0 提供的 proxyless service mesh 也是一個很好的選擇,它可以幫助你以最低的成本助你從微服務體系接入 istio 控制面。當然,dubbogo 的控制面能力還需要進一步加強,在未來的 3.1 版本中提供 proxyless 和 proxy 兩套 service mesh 方案。
二 Dubbo-go 3.0 有哪些不同
Apache 軟件基金會頂級項目 Dubbo 開源至今已有十年時間,而作為第三個里程碑,也是雲原生時代的全新版本,Dubbo 3.0 的研發工作最早可以追溯到2018年,作為 Dubbo 多語言生態的重要一環,Dubbo-go 社區也在2020年年底,將 3.0 版本作為主推方向。
在官方新特性支持(Triple 協議、應用級服務發現、路由規則、柔性服務等等)的基礎之上,Dubbo-go 社區針對使用友好性,多語言多生態的兼容性,用戶編程和使用習慣等方面重點進行了優化,與其說 Go 社區的 3.0 是一次版本對齊的迭代,不如說是一個富有生命力的新開始。
1 新配置方案
- 配置結構
在 3.0 時代,我們更清晰地規范出了應用層級配置和接口層級配置的概念,相比於之前版本,在配置結構上進行了重構和精簡化。例如開發者在微服務場景之下,會關注注冊中心地址、協議、接口名等信息。只需要在配置文件中制定好:
- 配置中心
在 Dubbo-go 3.0 中,可以將上述框架配置或用戶配置放置在配置中心內便於管理。在容器內只需要放置配置中心相關信息即可基於該配置啟動框架。
- 配置API
開發者可以在代碼內通過配置 API 生成配置實例結構,代碼中生成的配置與從文件內讀取的配置等價。參考於 Java Builder 的設計來自於社區同學們,也代表了開發者對於接口易用性的訴求。
2 Triple + PB 協議
Dubbo-go 在上半年首次發布的 3.0.0-rc1 版本內已經支持 Triple 協議。在此期間,由合作方釘釘部門相關同學提出了較多針對響應時延、穩定性等優化建議。時至今日,在性能、用戶使用體驗、泛化調用、異常回傳、PB反射等方面都進行了大量的優化工作。
- 性能優化
將舊版本基於 net/http2 的實現切換為基於 grpc 的 http2 層實現方案。增強了底層傳輸的穩定性和性能。經過壓測,4c8g 單機 Provider 可以處理 7萬 tps 的簡單請求。
我們使用了 3 台相同規格機器,一台作為Server(運行一個 triple-server),一台作為Client(運行一個triple-server 和triple client) ,一台作為施壓機向 Client 發起針對整個鏈路的調用施壓,並進行數據記錄,記錄rt、真實 tps 以及client 和 server 的 CPU 占比數據。
- 反射支持
Triple 默認開啟 proto 反射,用戶可以使用 grpc_cli 針對 Triple 協議暴露的pb序列化服務進行展示和調試。
在 proto 反射支持的前提下,dubbo-go-pixiu 提供了網關層協議轉換調用 triple 服務的支持。
- 用戶編程方式
新 PB 編譯插件,新版本 dubbo-go 推薦 go 用戶使用 proto 文件定義接口,與 gRPC-go 的使用方式類似。
關於 Triple 協議,最早是阿里雲中間件團隊在 Dubbo3 形成概念的時候就提出的。它相比於上一代 Dubbo 協議,解決了 Dubbo 生態與其他雲原生架構生態不互通的特點,並且用戶很難理解位於傳輸層的上一代二進制協議。基於 HTTP2 協議的 gRPC 擴展協議就很好滴解決了這一問題。第二是點是對 Mesh 等網關型組件不夠友好,在 3.0 時代,我們可以直接通過解析協議頭來獲取必要的元數據,並很自然地適配網關對於 HTTP 協議的轉發實現。
從我們社區所對接的 Go 語言開發者考慮,PB 序列化更能適配與他們的開發習慣,方便從已有 gRPC 服務遷移業務代碼,還解決了升級過程中跨協議通信的兼容性問題,而在使用 Triple 協議后,跨語言互通的優勢將進一步體現,從“可互通” 轉變為基於成熟序列化方案的“穩定性互通”,方便用戶業務更廣泛的擴展,簡單來說,在 Dubbo 時代,用戶進行跨語言互通需要依賴多語言生態的 Dubbo 協議實現,而在3.0 時代,您可以使用任意語言的 gRPC 實現來與 Dubbo 服務直接進行互通,並共享 gRPC 生態的一系列組件,例如鏈路追蹤、可視化、cli 工具等等。
因此,我們認為 Triple 的意義並不是一個簡單的擴展協議,而是一個跨語言、跨生態概念的實現,也是 Dubbo3 的核心 Feature 所在。
3 柔性服務
大規模分布式系統承載的用戶流量呈指數級增長,需要使用負載均衡算法將流量均勻地分散到各個機器中,提升集群的吞吐率和資源利用率。
傳統負載均衡算法大多是基於消費者視角,它們共同的局限性是無法根據服務提供者的當前狀態動態調整分流策略,如 RR、hash 等算法。這些算法總是以盡可能公平的概率分配流量,但在實踐中公平不等於負載均衡。
我們期望的均衡分流策略是:
- 動態性能評估:用戶不需要事先設置機器權重,框架在運行時自動評估系統性能,性能好的機器承擔更多流量,性能不足的機器承擔更少的流量;
- 故障自愈能力:負載均衡算法能夠自動摘除故障的節點,並具備故障自愈能力;
- 適當限流策略:避免服務雪崩問題。
柔性服務作為新一代負載均衡策略被引入 Dubbo-go 3.0 中,核心能力包括容量評估和智能分流。
容量評估是評估當前服務提供者狀態以保持最優請求隊列長度。容量評估關注的兩個核心指標是 TPS 和延遲,TPS 評估系統的每秒處理事物的速度,延遲反映用戶等待時間。在評估服務端容量時,要平衡系統吞吐率和用戶等待時間兩者之間的關系,理想狀態下在系統吞吐率盡可能大的情況下用戶延遲盡可能小。
HillClimbing 算法作用於服務提供者,周期性地判定當前是否處於最佳狀態並動態更新系統容量。
探測間隔隨着時間逐步拉長,直至趨向穩定。剛啟動時沒有歷史數據,此時需要頻繁更新容量評估值,保證系統以盡可能快的速度探測到最優容量。我們假定最優容量短時間內不會再強烈波動,且容量評估也會額外消耗資源,因此當趨向穩定的時候,算法將逐步延長探測周期。
容量更新策略與 TCP 擁塞控制相似。下面公示表示 HillClimbing 算法預設的兩種增量類型:
在初期采用慢啟動策略,取一個較低水平的值作為容量初始值,但是以較高增量(alpha)向最優容量逼近。如果當前容量已經增長到 TPS 降低的情況,則使用較低增量(beta)以更精准的方式向最優容量移動。
在每次調用過程結束后,服務提供者會通過 Dubbo-go 的附件(attachment)特性將最新的預估容量返回給服務消費者,消費者將信息緩存至本地並使用 P2C 算法實現智能分流。
P2C(Pick Two Random Choices)算法作用於服務消費者,它有着更科學的負載均衡策略並廣泛的應用在多個知名開源項目中,如 Linkerd、Rsocket 等。該算法首先隨機選擇兩個節點,然后對比節點的剩余容量,選擇其中一個剩余容量較多的節點作為本次調用的服務提供者。
柔性服務將在后續版本中持續優化,與 Dubbo 社區共同探索出一套適合微服務場景的柔性服務最佳實踐。
4 Pixiu 網關
Dubbo-go-pixiu 網關支持調用 GO/Java 的 Dubbo 集群。在 Dubbo-go 3.0 的場景下,我們可以通過 Pixiu 網關,在集群外以 HTTP 協議請求 pixiu 網關,在網關層進行協議轉換,進一步調用集群內的Dubbo-go 服務。
例如一個proto文件內有如下定義:
並在dubbo-go 服務啟動時在dubbogo.yml 內配置應用名為my-dubbogo-app:
pixiu 網關即可解析 path 為 my-dubbogo-app/org.apache.dubbo.quickstart.samples.UserProvider/SayHello 的路由,並轉發至對應服務。來自外部HTTP 請求的 body 為 json 序列化的請求參數,例如 {"name":"test"}。
我們目前推薦使用 Nacos 作為注冊中心。
用戶可以在自己的集群里部署我們的demo,集群最好擁有暴露 lb 類型 service 的能力,從而可以在公網訪問至集群內的服務,您也可以直接集群內進行請求。
針對您的集群,執行:
會在 dubbogo-triple-nacos 命名空間下創建如下資源,包含三個 triple-server,一個pixiu網關,一個 nacos server。並通過 Servcie 將服務暴露至公網。
獲取 pixiu 公網 ip 並進行調用
通過curl 調用 demo 服務,並獲得響應結果。
5 運維能力與工具
- 可觀測性
相比於上一版本的 Dubbo-go,本次發布在原來Dubbo協議的可觀測性的基礎上,提供了基於 Triple 協議可觀測性支持,適配於 Jaeger 的鏈路追蹤展示。對於數據上報,我們在框架中為之提供了接口,方便用戶實時上報業務埋點數據,並默認開啟 promehteus 的拉模式數據收集的支持。
框架對於 RPC調用相關信息,例如請求RT,接口名、方法名等數據,也提供了默認的 metrics 字段,供用戶收集和統計。
- 日志
本次發版對日志模塊進行了較大的改變和更新,用戶可以根據需求配置日志打印的級別、分片、文件輸出、保留時常等信息,並支持用戶自定義日志組件。
- cli工具
Dubbo-go 3.0 會針對命令行工具進行重點開發,目前社區已提供用於發起 Dubbo RPC 調用的dubbo-go-cli;用於編譯 pb 文件的protoc-gen-go-triple 插件;並且 Dubbo-go 已經適配 grpc_cli 工具的調試,在未來,我們會在健康檢查、服務信息獲取、RPC 調用調試、框架代碼初始化和接口編譯、服務部署等方面,進一步增強命令行工具的能力,以提供更完備的服務治理和運維生態。
三 用戶視角的 Dubbo-go
作為一款站在用戶角度設計的框架,我們更希望給予廣大用戶更簡潔,更直觀,更“約定大於配置”的使用體驗,因此在研發階段,我們重點進行了多輪的配置迭代以及 samples 倉庫的建設和維護,為用戶提供了更為精簡的概念和重點突出的 samples 示例。
1 面向接口和配置的開發
Dubbo-go 3.0 為開發者屏蔽掉了底層實現細節,只需要關注幾個關鍵點即可使用本框架進行開發,以 triple 服務為例。
- 框架配置文件:dubbogo.yaml
框架啟動所依賴的配置項。
- 接口定義
編寫 proto 文件,並使用提供的 protoc-gen-go-triple 插件以及官方 protoc-gen-go 插件進行編譯。
- 接口代碼實現
編寫服務實現,並使用框架進行啟動即可。
接口、實現、配置。是常見 go 微服務的基本依賴元素。Dubbo-go 提供一整套微服務的解決方案,並提供豐富的服務治理能力和可擴展能力,從而可以讓用戶容易地接入使用。
2 代碼示例倉庫 dubbo-go-samples
我們在apache/dubbo-go-samples 倉庫的 master 分支維護了豐富的 dubbo-go 3.0 的代碼示例。包括多種協議的 rpc 調用,多種注冊中心的支持,多種配置中心的使用,以及泛化調用、配置API、日志、數據上報、鏈路追蹤等運維能力的展示,幾乎框架擁有的全部能力都可以在 samples 倉庫中找到對應的常見用例。用戶也可以在1.5分支找到適配與dubbo-go 1.5.x 的示例。
通過 3.0 前期階段對於配置重構和大幅度的用戶友好性優化,目前 samples 倉庫內的代碼和配置都已經高度精簡化,從而突出單個模塊的能力。開發者可以下載倉庫后直接按照server 到 client 的順序來玩耍一個示例模塊的服務,即可體驗框架提供的能力。
samples 倉庫在迭代過程中也被賦予了更多的功能,社區開發同學都會熟悉,我們將框架倉庫、samples 倉庫通過 ci 集成測試的方式結合起來,保證框架開發者每次提交的代碼都能通過所有用例的 e2e 測試,從而保障開發質量,提高迭代的效率。
四 社區協作
作為一個能力功能非常豐富的服務平台,dubbogo 社區很重視與各大開源社區特別是阿里系開源產品社區以及各個公司的合作。
- Nacos 社區
早期 Dubbo-go 社區就與 Nacos 社區展開密切合作,由多位核心貢獻者參與 Dubbo-go 研發支持中,在 3.0.0 版本中,增加了多位 Nacos 社區成員,在社區迭代中作出了許多建設性的建議和貢獻。
- Polaris 社區
北極星(Polaris)是騰訊開源的服務發現和治理中心,致力於解決分布式或者微服務架構中的服務可見、故障容錯、流量控制和安全問題。在 3.0.0 版本的開發中,Dubbo-go 社區與 Polaris 社區展開合作,實現了把 Polaris 作為 dubbo-go 的注冊中心。
- Sentinel-Golang 社區
Sentinel 是面向分布式服務架構的流量控制組件,在Sentinel-Golang 首個版本 0.1.0 正式發布后,Dubbo-go 社區就與 Sentinel-Golang 社區展開密切合作,在功能上支持 Sentinel-Golang 作為流量控制。
- Seata-golang 社區
從 dubbogo v1.3 開始, 就集成了 seata-golang,實現了 TCC 模式分布式事務的調用。
- 其他公司
dubbogo 本身是一個有着極高生產環境需求的項目,在發展過程中與阿里等很多公司有過合作。這些合作使得雙方都有收益,dubbogo 的質量得以保證,功能得以拓展,合作方自身的平台穩定性得到極大提升。
五 展望
前面講到,Dubbo-go 3.0 對我們來說是一個新時代的起點,在未來的迭代中,我們除了繼續維護上述流量調度以及服務治理能力之外,還會基於如下幾個方向重點發力。
1 流量路由規則
Dubbo-go 3.0 在路由規則方面設計與 dubbo 一致,提供了支持 mesh 方式的路由規則策略並接入了 dubbo-admin 這一控制面板。
在 mesh 路由方面,dubbo-go 將路由規則分為 VirtualService 和 DestinationRule 兩部分,其中 DestinationRule 定義了目標地址的規則,通過 subset 和 host 關聯到對應的集群,而 VirtualService 則定義了具體的路由匹配規則。當客戶端發起一次調用時,首先經過 VirtualService 路由到具體的 subset,然后根據 DestinationRule 中對應 subset 的 labels 信息找到具體的集群。這種設計方式將路由規則和目標地址進行了解耦,支持 VirtualService 和 DestinationRule 的多種組合,實現了更加靈活的路由策略,也可以更加輕易實現 A/B 測試、金絲雀發布、藍綠發布等能力。
關於接入 dubbo-admin 一塊工作,目前 dubbo-go 已經重構了 zookeeper 配置中心的代碼邏輯,並實現了和 dubbo-admin 互通,即用戶可以在 dubbo-admin 上動態發布、更新路由來調度集群內流量(目前僅限 zookeeper),而應用可以立即感知,無需重啟。在不久的未來我們會繼續深入打通這一部分的能力互通,支持 nacos 等其他常用配置中心、注冊中心的互通,徹底實現控制面板與數據面板的分離。
2 統一控制面與服務架構創新
我們將推出兼容 Dubbo-admin 的統一控制面,可在控制面中通過路由配置動態調度集群內流量,將新路由規則以更靈活、更易用的方式落地在生產場景下,運維人員也可以在控制面上一目了然地了解到集群內 dubbo-go 應用的實時情況,進一步來講,控制面將會擁有服務測試、灰度發布、監控、流量調度等一系列運維能力。
我們還會在適配於 pixiu 網關協議轉換的基礎之上,進一步發掘網關的能力,朝 proxyless service-mesh 的方向探索新的微服務架構。
3 進一步雲原生化
我們將在 dubbo-go 1.5 版本在 k8s 方向探索的基礎之上,進一步支持雲原生能力,計划包含探針、配置、資源監聽等方面,使得框架在雲原生架構下具有更好的使用體驗,更多樣的服務治理能力。
原文鏈接
本文為阿里雲原創內容,未經允許不得轉載。