从编程开发的角度来说,Apache Dubbo (以下简称 Dubbo)首先是一款 RPC 服务框架,它最大的优势在于提供了面向接口代理的服务编程模型,对开发者屏蔽了底层的远程通信细节。同时 Dubbo 也是一款服务治理框架,它为分布式部署的微服务提供了服务发现、流量调度等服务治理解决方案。
public interface GreetingsService {
String sayHi(String name);
}
// 和调用本地服务一样,完全透明。
@Reference
private GreetingService greetingService;
public void doSayHello(String name) {
greetingService.sayHi("Hello world!");
}
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService1" protocol="dubbo"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService2" protocol="dubbo"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService3" protocol="grpc"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService4" protocol="grpc"/>
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService0" protocol="dubbo, grpc"/>
<dubbo:reference protocol="dubbo" interface="org.apache.dubbo.samples.basic.api.DemoService1"/>
<dubbo:reference protocol="dubbo" interface="org.apache.dubbo.samples.basic.api.DemoService2"/>
<dubbo:reference protocol="grpc" interface="org.apache.dubbo.samples.basic.api.DemoService0"/>
<dubbo:reference protocol="grpc" interface="org.apache.dubbo.samples.basic.api.DemoService3"/> <dubbo:reference protocol="grpc" interface="org.apache.dubbo.samples.basic.api.DemoService4"/>
<dubbo:reference protocol="dubbo" interface="org.apache.dubbo.samples.basic.api.DemoService0"/>
Dubbo 目前所支持的协议包括 Dubbo、REST、Thrift、gRPC、JsonRPC、Hessian 等,基本涵盖了业界大多数主流的 RPC 通信协议。需要注意的是,这些协议的支持都是以直接集成官方 Release 实现的形式来做的,我认为这是一个很好的选择,既保证了协议解析自身的稳定性,又能使 Dubbo 社区更专注的将更多的精力放在 Dubbo 外围服务治理能力的改善上。试想如果 Dubbo 社区自己为每个协议提供实现,那是要花费多少精力和时间才能使每种协议达到稳定的生产可用。
多协议能解决的问题
将 RPC 框架无缝地接入 Dubbo 的服务治理体系。
通过协议扩展将 RPC 协议纳入 Dubbo 服务开发体系,从而复用 Dubbo 的编程模型和服务发现、流量管控等能力。比如 gRPC,其服务治理体系相对比较弱、编程 API 不够友好,很难直接用于微服务开发。
<dubbo:registry id="beijingRegistry" address="zookeeper://${zookeeper.address1}" default="false"/> <dubbo:registry id="shanghaiRegistry" address="zookeeper://${zookeeper.address2}" />
<dubbo:service interface="org.apache.dubbo.samples.multi.registry.api.HelloService" ref="helloService" registry="shanghaiRegistry,beijingRegistry"/>
<dubbo:service interface="org.apache.dubbo.samples.multi.registry.api.DemoService" ref="demoService" registry="shanghaiRegistry,beijingRegistry"/>
<dubbo:registry id="beijingRegistry" address="zookeeper://${zookeeper.address1}" default="false" preferred="true" weight="100"/> <dubbo:registry id="shanghaiRegistry" address="zookeeper://${zookeeper.address2}" default="true" weight="20"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.DemoService"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.DemoService" registry="beijingRegistry, shanghaiRegistry"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.HelloService" registry="beijingRegistry"/>
<dubbo:reference interface="org.apache.dubbo.samples.multi.registry.api.HelloService" registry="shanghaiRegistry,shanghaiRegistry"/>
虽然我们会做多注册中心集群部署,但通常情况下,我们部署的都是相同的注册中心产品,如都是 Zookeeper、Nacos;而对于注册中心迁移的场景,则要求 Dubbo 能提供对更多的注册中心产品的支持,或者最重要的是要有很好的扩展能力。Dubbo 官方目前支持的注册中心实现有:
<!-- 来自 preferred=“true” 注册中心的地址将被优先选择,只有该中心无可用地址时才 Fallback 到其他注册中心 -->
<dubbo:registry address="zookeeper://${zookeeper.address1}" preferred="true" />
<!-- 选址时会和流量中的 zone key 做匹配,流量会优先派发到相同 zone 的地址 -->
<dubbo:registry address="zookeeper://${zookeeper.address1}" zone="beijing" />
<!-- 来自北京和上海集群的地址,将以 10:1 的比例来分配流量 -->
<dubbo:registry id="beijing" address="zookeeper://${zookeeper.address1}" weight=”100“ />
<dubbo:registry id="shanghai" address="zookeeper://${zookeeper.address2}" weight=”10“ />
如上图所示,我们有部分微服务可以是基于 SpringCloud、gRPC、K8S 或者是自建体系构建的,他们各自之间默认是相互隔离无法联通的。当我们再构建一套基于 Dubbo 的微服务体系时,则利用 Dubbo 的多协议、多服务发现模型,我们就可以做到和各个微服务体系间的两两之间的互联互通。进一步的,如图中橙色箭头所示,依赖 Dubbo 体系作为桥接层,我们还可以实现两个异构微服务体系间的打通。
当前在云原生、Mesh 的大背景下, HTTP1/2、gRPC 协议开始受到越来越多的关注,一方面原因自然是因为它们在标准化方面做的更好,得到的更多的网络设备和基础设施的支持,具备更好的通用性和穿透性。对于很多有云原生迁移意愿的企业来说,往此类协议迁移无疑将对之后的架构升级有更多的帮助。
Dubbo 体系内的部分应用作为透明的联通两个体系的关键节点,部分服务提供者应用要双协议发布、部分消费者应用要做到选定协议消费。由于老的 Spring Cloud 体系不允许做任何改动,因此联通两套体系的关键是 REST 协议,对 Dubbo 侧的应用来说:
<dubbo:reference interface ="xxx.SpringService" protocol="rest"/>
<dubbo:service interface="xxx.NewService" protocol="rest,dubbo"/>
作为 Dubbo 的维护者,虽然我们这里有明显的偏向性,讲的是从如何从 SpringCloud 体系迁移到 Dubbo 体系。但是反过来考虑,如果你已经或者即将选型 Dubbo 来开发微服务,则未来从 Dubbo 迁移到 SpringCloud 也是同样的思路,Dubbo 的多协议、多注册模型为双向迁移都提供了同样的灵活性。
http://dubbo.apache.org/zh-cn/docs/dev/impls/protocol.html
作者:刘军,GitHub账号Chickenlj,Apache Dubbo PMC,项目核心维护者,见证了Dubbo从重启开源到Apache毕业的整个流程。现任职阿里云云原生应用平台团队,参与服务框架、微服务相关工作,目前主要在推动Dubbo开源的云原生化。
本文缩略图:icon by Dora1900