Dubbo 2.7三大特性详解
1 背景介紹
自 2017 年 7 月阿里重啟 Dubbo 開源,到目前為止 github star 數(shù),contributor 數(shù)都有了非常大的提升。2018 年 2 月 9 日阿里決定將 Dubbo 項目貢獻(xiàn)給 Apache,經(jīng)過一周的投票,順利成為了 Apache 的孵化項目,也就是大家現(xiàn)在看到的?Incubator Dubbo。預(yù)計在 2019 年 4 月,Dubbo 可以達(dá)成畢業(yè),成為 Apache 的頂級項目。
2 分支介紹
Dubbo 目前有如圖所示的 5 個分支,其中 2.7.1-release 只是一個臨時分支,忽略不計,對其他 4 個分支進(jìn)行介紹。
- 2.5.x 近期已經(jīng)通過投票,Dubbo 社區(qū)即將停止對其的維護(hù)。
- 2.6.x 為長期支持的版本,也是 Dubbo 貢獻(xiàn)給 Apache 之前的版本,其包名前綴為:com.alibaba,JDK 版本對應(yīng) 1.6。
- 3.x-dev 是前瞻性的版本,對 Dubbo 進(jìn)行一些高級特性的補(bǔ)充,如支持 rx 特性。
- master 為長期支持的版本,版本號為 2.7.x,也是 Dubbo 貢獻(xiàn)給 Apache 的開發(fā)版本,其包名前綴為:org.apache,JDK 版本對應(yīng) 1.8。
如果想要研究 Dubbo 的源碼,建議直接瀏覽 master 分支。
3 Dubbo 2.7 新特性
Dubbo 2.7.x 作為 Apache 的孵化版本,除了代碼優(yōu)化之外,還新增了許多重磅的新特性,本文將會介紹其中最典型的三個新特性:
- 異步化改造
- 三大中心改造
- 服務(wù)治理增強(qiáng)
4 異步化改造
4.1 幾種調(diào)用方式
在遠(yuǎn)程方法調(diào)用中,大致可以分為這 4 種調(diào)用方式。oneway 指的是客戶端發(fā)送消息后,不需要接受響應(yīng)。對于那些不關(guān)心服務(wù)端響應(yīng)的請求,比較適合使用 oneway 通信。
注意,void hello() 方法在遠(yuǎn)程方法調(diào)用中,不屬于 oneway 調(diào)用,雖然 void 方法表達(dá)了不關(guān)心返回值的語義,但在 RPC 層面,仍然需要做通信層的響應(yīng)。
sync 是最常用的通信方式,也是默認(rèn)的通信方法。
future 和 callback 都屬于異步調(diào)用的范疇,他們的區(qū)別是:在接收響應(yīng)時,future.get() 會導(dǎo)致線程的阻塞;callback 通常會設(shè)置一個回調(diào)線程,當(dāng)接收到響應(yīng)時,自動執(zhí)行,不會對當(dāng)前線程造成阻塞。
4.2 Dubbo 2.6 異步化
異步化的優(yōu)勢在于客戶端不需要啟動多線程即可完成并行調(diào)用多個遠(yuǎn)程服務(wù),相對多線程開銷較小。介紹 2.7 中的異步化改造之前,先回顧一下如何在 2.6 中使用 Dubbo 異步化的能力。
可以看出,這樣的使用方式,不太符合異步編程的習(xí)慣,竟然需要從一個上下文類中獲取到 Future。如果同時進(jìn)行多個異步調(diào)用,使用不當(dāng)很容易造成上下文污染。而且,Future 并不支持 callback 的調(diào)用方式。這些弊端在 Dubbo 2.7 中得到了改進(jìn)。
4.3 Dubbo 2.7 異步化
Dubbo 2.7 中使用了 JDK1.8 提供的?CompletableFuture?原生接口對自身的異步化做了改進(jìn)。CompletableFuture?可以支持 future 和 callback 兩種調(diào)用方式,用戶可以根據(jù)自己的喜好和場景選擇使用,非常靈活。
4.4 異步化設(shè)計 FAQ
Q:如果 RPC 接口只定義了同步接口,有辦法使用異步調(diào)用嗎?
A:2.6 中的異步調(diào)用唯一的優(yōu)勢在于,不需要在接口層面做改造,又可以進(jìn)行異步調(diào)用,這種方式仍然在 2.7 中保留;使用 Dubbo 官方提供的 compiler hacker,編譯期自動重寫同步方法,請在此討論和跟進(jìn)具體進(jìn)展。
Q:關(guān)于異步接口的設(shè)計問題,為何不提供編譯插件,根據(jù)原接口,自動編譯出一個 XxxAsync 接口?
A:Dubbo 2.7 采用過這種設(shè)計,但接口的膨脹會導(dǎo)致服務(wù)類的增量發(fā)布,而且接口名的變化會影響服務(wù)治理的一些相關(guān)邏輯,改為方法添加 Async 后綴相對影響范圍較小。
Q:Dubbo 分為了客戶端異步和服務(wù)端異步,剛剛你介紹的是客戶端異步,為什么不提服務(wù)端異步呢?
A:Dubbo 2.7 新增了服務(wù)端異步的支持,但實際上,Dubbo 的業(yè)務(wù)線程池模型,本身就可以理解為異步調(diào)用,個人認(rèn)為服務(wù)端異步的特性較為雞肋。
5 三大中心改造
三大中心指的:注冊中心,元數(shù)據(jù)中心,配置中心。
在 2.7 之前的版本,Dubbo 只配備了注冊中心,主流使用的注冊中心為 zookeeper。新增加了元數(shù)據(jù)中心和配置中心,自然是為了解決對應(yīng)的痛點,下面我們來詳細(xì)闡釋三大中心改造的原因。
5.1 元數(shù)據(jù)改造
元數(shù)據(jù)是什么?元數(shù)據(jù)定義為描述數(shù)據(jù)的數(shù)據(jù),在服務(wù)治理中,例如服務(wù)接口名,重試次數(shù),版本號等等都可以理解為元數(shù)據(jù)。在 2.7 之前,元數(shù)據(jù)一股腦丟在了注冊中心之中,這造成了一系列的問題:
推送量大 -> 存儲數(shù)據(jù)量大 -> 網(wǎng)絡(luò)傳輸量大 -> 延遲嚴(yán)重
生產(chǎn)者端注冊 30+ 參數(shù),有接近一半是不需要作為注冊中心進(jìn)行傳遞;消費者端注冊 25+ 參數(shù),只有個別需要傳遞給注冊中心。有了以上的理論分析,Dubbo 2.7 進(jìn)行了大刀闊斧的改動,只將真正屬于服務(wù)治理的數(shù)據(jù)發(fā)布到注冊中心之中,大大降低了注冊中心的負(fù)荷。
同時,將全量的元數(shù)據(jù)發(fā)布到另外的組件中:元數(shù)據(jù)中心。元數(shù)據(jù)中心目前支持 redis(推薦),zookeeper。這也為 Dubbo 2.7 全新的 Dubbo Admin 做了準(zhǔn)備,關(guān)于新版的 Dubbo Admin,我將會后續(xù)準(zhǔn)備一篇獨立的文章進(jìn)行介紹。
示例:使用 zookeeper 作為元數(shù)據(jù)中心
<dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>5.2 Dubbo 2.6 元數(shù)據(jù)
dubbo://30.5.120.185:20880/com.alibaba.dubbo.demo.DemoService? anyhost=true& application=demo-provider& interface=com.alibaba.dubbo.demo.DemoService& methods=sayHello& bean.name=com.alibaba.dubbo.demo.DemoService& dubbo=2.0.2& executes=4500& generic=false& owner=kirito& pid=84228& retries=7& side=provider& timestamp=1552965771067從本地的 zookeeper 中取出一條服務(wù)數(shù)據(jù),通過解碼之后,可以看出,的確有很多參數(shù)是不必要。
5.3 Dubbo 2.7 元數(shù)據(jù)
在 2.7 中,如果不進(jìn)行額外的配置,zookeeper 中的數(shù)據(jù)格式仍然會和 Dubbo 2.6 保持一致,這主要是為了保證兼容性,讓 Dubbo 2.6 的客戶端可以調(diào)用 Dubbo 2.7 的服務(wù)端。如果整體遷移到 2.7,則可以為注冊中心開啟簡化配置的參數(shù):
<dubbo:registry address=“zookeeper://127.0.0.1:2181” simplified="true"/>Dubbo 將會只上傳那些必要的服務(wù)治理數(shù)據(jù),一個簡化過后的數(shù)據(jù)如下所示:
dubbo://30.5.120.185:20880/org.apache.dubbo.demo.api.DemoService? application=demo-provider& dubbo=2.0.2& release=2.7.0& timestamp=1552975501873對于那些非必要的服務(wù)信息,仍然全量存儲在元數(shù)據(jù)中心之中:
元數(shù)據(jù)中心的數(shù)據(jù)可以被用于服務(wù)測試,服務(wù) MOCK 等功能。目前注冊中心配置中 simplified 的默認(rèn)值為 false,因為考慮到了遷移的兼容問題,在后續(xù)迭代中,默認(rèn)值將會改為 true。
5.4 配置中心支持
衡量配置中心的必要性往往從三個角度出發(fā):
分布式配置統(tǒng)一管理
動態(tài)變更推送
安全性
Spring Cloud Config, Apollo, Nacos 等分布式配置中心組件都對上述功能有不同程度的支持。在 2.7 之前的版本中,在 zookeeper 中設(shè)置了部分節(jié)點:configurators,routers,用于管理部分配置和路由信息,它們可以理解為 Dubbo 配置中心的雛形。在 2.7 中,Dubbo 正式支持了配置中心,目前支持的幾種注冊中心 Zookeeper,Apollo,Nacos(2.7.1-release 支持)。
在 Dubbo 中,配置中心主要承擔(dān)了兩個作用
-
外部化配置。啟動配置的集中式存儲
-
服務(wù)治理。服務(wù)治理規(guī)則的存儲與通知
示例:使用 Zookeeper 作為配置中心
<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>引入配置中心后,需要注意配置項的覆蓋問題,優(yōu)先級如圖所示
6 服務(wù)治理增強(qiáng)
我更傾向于將 Dubbo 當(dāng)做一個服務(wù)治理框架,而不僅僅是一個 RPC 框架。在 2.7 中,Dubbo 對其服務(wù)治理能力進(jìn)行了增強(qiáng),增加了標(biāo)簽路由的能力,并抽象出了應(yīng)用路由和服務(wù)路由的概念。在最后一個特性介紹中,著重對標(biāo)簽路由 TagRouter 進(jìn)行探討。
在服務(wù)治理中,路由層和負(fù)載均衡層的對比。區(qū)別 1,Router:m 選 n,LoadBalance:n 選 1;區(qū)別 2,路由往往是疊加使用的,負(fù)載均衡只能配置一種。
在很長的一段時間內(nèi),Dubbo 社區(qū)經(jīng)常有人提的一個問題是:Dubbo 如何實現(xiàn)流量隔離和灰度發(fā)布,直到 2.7 提供了標(biāo)簽路由,用戶可以使用這個功能,來實現(xiàn)上述的需求。
標(biāo)簽路由提供了這樣一個能力,當(dāng)調(diào)用鏈路為 A -> B -> C -> D 時,用戶給請求打標(biāo),最典型的打標(biāo)方式可以借助 attachment(他可以在分布式調(diào)用中傳遞下去),調(diào)用會優(yōu)先請求那些匹配的服務(wù)端,如 A -> B,C -> D,由于集群中未部署 C 節(jié)點,則會降級到普通節(jié)點。
打標(biāo)方式會收到集成系統(tǒng)差異的影響,從而導(dǎo)致很大的差異,所以 Dubbo 只提供了RpcContext.getContext().setAttachment()?這樣的基礎(chǔ)接口,用戶可以使用 SPI 擴(kuò)展,或者 server filter 的擴(kuò)展,對測試流量進(jìn)行打標(biāo),引導(dǎo)進(jìn)入隔離環(huán)境/灰度環(huán)境。
新版的 Dubbo Admin 提供了標(biāo)簽路由的配置項:
Dubbo 用戶可以在自己系統(tǒng)的基礎(chǔ)上對標(biāo)簽路由進(jìn)行二次擴(kuò)展,或者借鑒標(biāo)簽路由的設(shè)計,實現(xiàn)自己系統(tǒng)的流量隔離,灰度發(fā)布。
7 總結(jié)
本文介紹了 Dubbo 2.7 比較重要的三大新特性:異步化改造,三大中心改造,服務(wù)治理增強(qiáng)。Dubbo 2.7 還包含了很多功能優(yōu)化、特性升級,可以在項目源碼的?CHANGES.md?中瀏覽全部的改動點。最后提供一份 Dubbo 2.7 的升級文檔:2.7遷移文檔,歡迎體驗。
原文:http://dubbo.apache.org/zh-cn/blog/dubbo-27-features.html
總結(jié)
以上是生活随笔為你收集整理的Dubbo 2.7三大特性详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 研究 Dubbo 网卡地址注册时的一点思
- 下一篇: spring整合webservice