看一下“Dubbo 2.7”的三大新特性


Dubbo 2.7.x 作為 Apache 的孵化版本,除了代碼優化之外,還新增了許多重磅的新特性,本文將會介紹其中最典型的三個新特性:

  • 一、異步化改造
  • 二、三大中心改造
  • 三、服務治理增強
看一下“Dubbo 2.7”的三大新特性

 

一、異步支持優化

我們知道dubbo協議本身支持三種發送請求方式:

單向發送:執行方法不需要返回結果

同步發送:執行方法后,等待結果返回,否則一直阻塞.

異步發送:也就是當我發送調用后,我不阻塞等待結果,直接返回,將返回的future保存到上下文,方便后期使用。在異步發送中有兩種方式分別是

future:當請求有響應后,通過future.get()來獲得響應結果,但是future.get()會導致線程阻塞,future從RpcContext獲取。

callback:設置一個回調線程,當接收到響應時,自動執行,不會對當前線程造成阻塞,自定義ResponseFuture支持callback。

2.6.x版本的異步方式提供了一些異步能力,包括Consumer端異步調用、參數回調、事件通知等。但當前的異步方式存在以下問題:

Future獲取方式不夠直接,只能在RpcContext中進行獲取;

Future只支持阻塞式的get()接口獲取結果。

Future接口無法實現自動回調,而自定義ResponseFuture雖支持callback回調但支持的異步場景有限,如不支持Future間的相互協調或組合等;

不支持Provider端異步

 

那么在2.7.x版本,由於JDK版本升級到了1.8,引入了JDK1.8 中的CompletableFuture接口,CompletableFuture支持 future 和 callback 兩種調用方式。關於CompletableFuture怎么被運用到dubbo中我會在后續的文章介紹。引入該接口后,做了以下優化:

支持Provider端異步

支持直接定義返回CompletableFuture的服務接口。通過這種類型的接口,我們可以更自然的實現Consumer、Provider端的異步編程。

public interface AsyncService { 
CompletableFuture<String> sayHello(String name);
}

如果你不想將接口的返回值定義為Future類型,或者存在定義好的同步類型接口,則可以額外定義一個異步接口並提供Future類型的方法。

public interface GreetingsService { 
String sayHi(String name);
}
@AsyncFor(GreetingsService.class)
public interface GrettingServiceAsync extends GreetingsService {
CompletableFuture<String> sayHiAsync(String name);
}

如果你的原始接口定義不是Future類型的返回值,Provider端異步也提供了類似Servlet3.0里的Async Servlet的編程接口: RpcContext.startAsync()

public interface AsyncService { 
String sayHello(String name);
}
public class AsyncServiceImpl implements AsyncService {
public String sayHello(String name) {
final AsyncContext asyncContext = RpcContext.startAsync();
new Thread(() -> {

asyncContext.write("Hello " + name + ", response from provider.");
}).start();
return null;
}
}

異步過濾器鏈回調。

看一下“Dubbo 2.7”的三大新特性

 

二、三大中心改造

三大中心指的:注冊中心,元數據中心,配置中心。

在 2.7 之前的版本,Dubbo 只配備了注冊中心,主流使用的注冊中心為 zookeeper。新增加了元數據中心和配置中心,自然是為了解決對應的痛點,下面我們來詳細闡釋三大中心改造的原因。

元數據改造

元數據是什么?元數據定義為描述數據的數據,在服務治理中,例如服務接口名,重試次數,版本號等等都可以理解為元數據。在 2.7 之前,元數據一股腦丟在了注冊中心之中,這造成了一系列的問題:

推送量大 -> 存儲數據量大 -> 網絡傳輸量大 -> 延遲嚴重

生產者端注冊 30+ 參數,有接近一半是不需要作為注冊中心進行傳遞;消費者端注冊 25+ 參數,只有個別需要傳遞給注冊中心。有了以上的理論分析,Dubbo 2.7 進行了大刀闊斧的改動,只將真正屬於服務治理的數據發布到注冊中心之中,大大降低了注冊中心的負荷。

同時,將全量的元數據發布到另外的組件中:元數據中心。元數據中心目前支持 redis(推薦),zookeeper。這也為 Dubbo 2.7 全新的 Dubbo Admin 做了准備,關於新版的 Dubbo Admin,我將會后續准備一篇獨立的文章進行介紹。

示例:使用 zookeeper 作為元數據中心

<dubbo:metadata-report address="zookeeper://127.0.0.1:2181"/>

Dubbo 2.6 元數據

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 中取出一條服務數據,通過解碼之后,可以看出,的確有很多參數是不必要。

Dubbo 2.7 元數據

在 2.7 中,如果不進行額外的配置,zookeeper 中的數據格式仍然會和 Dubbo 2.6 保持一致,這主要是為了保證兼容性,讓 Dubbo 2.6 的客戶端可以調用 Dubbo 2.7 的服務端。如果整體遷移到 2.7,則可以為注冊中心開啟簡化配置的參數:

<dubbo:registry address=“zookeeper://127.0.0.1:2181” simplified="true"/>

Dubbo 將會只上傳那些必要的服務治理數據,一個簡化過后的數據如下所示:

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

元數據中心的數據可以被用於服務測試,服務 MOCK 等功能。目前注冊中心配置中 simplified 的默認值為 false,因為考慮到了遷移的兼容問題,在后續迭代中,默認值將會改為 true。

配置中心支持

衡量配置中心的必要性往往從三個角度出發:

  1. 分布式配置統一管理
  2. 動態變更推送
  3. 安全性

Spring Cloud Config, Apollo, Nacos 等分布式配置中心組件都對上述功能有不同程度的支持。在 2.7 之前的版本中,在 zookeeper 中設置了部分節點:configurators,routers,用於管理部分配置和路由信息,它們可以理解為 Dubbo 配置中心的雛形。在 2.7 中,Dubbo 正式支持了配置中心,目前支持的幾種注冊中心 Zookeeper,Apollo,Nacos(2.7.1-release 支持)。

在 Dubbo 中,配置中心主要承擔了兩個作用

  • 外部化配置。啟動配置的集中式存儲
  • 服務治理。服務治理規則的存儲與通知

示例:使用 Zookeeper 作為配置中心

<dubbo:config-center address="zookeeper://127.0.0.1:2181"/>

引入配置中心后,需要注意配置項的覆蓋問題。

看一下“Dubbo 2.7”的三大新特性

 

三、服務治理增強

如果我們把 Dubbo 當做一個服務治理框架,而不僅僅是一個 RPC 框架。在 2.7 中,Dubbo 對其服務治理能力進行了增強,增加了標簽路由的能力,並抽象出了應用路由和服務路由的概念。在最后一個特性介紹中,着重對標簽路由 TagRouter 進行探討。

在服務治理中,路由層和負載均衡層的對比。區別 1,Router:m 選 n,LoadBalance:n 選 1;區別 2,路由往往是疊加使用的,負載均衡只能配置一種。

在很長的一段時間內,Dubbo 社區經常有人提的一個問題是:Dubbo 如何實現流量隔離和灰度發布,直到 2.7 提供了標簽路由,用戶可以使用這個功能,來實現上述的需求。

看一下“Dubbo 2.7”的三大新特性

 

標簽路由提供了這樣一個能力,當調用鏈路為 A -> B -> C -> D 時,用戶給請求打標,最典型的打標方式可以借助 attachment(他可以在分布式調用中傳遞下去),調用會優先請求那些匹配的服務端,如 A -> B,C -> D,由於集群中未部署 C 節點,則會降級到普通節點。

打標方式會收到集成系統差異的影響,從而導致很大的差異,所以 Dubbo 只提供了 RpcContext.getContext().setAttachment() 這樣的基礎接口,用戶可以使用 SPI 擴展,或者 server filter 的擴展,對測試流量進行打標,引導進入隔離環境/灰度環境。新版的 Dubbo Admin 提供了標簽路由的配置項,Dubbo 用戶可以在自己系統的基礎上對標簽路由進行二次擴展,或者借鑒標簽路由的設計,實現自己系統的流量隔離,灰度發布。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM