不绑定 RPC 协议的设计原则
Aliware
Dubbo 框架不绑定任何通信协议,你可以根据业务场景选择 HTTP/2 通信协议,也可以选用 HTTP/REST、TCP(Dubbo2)、gRPC、JsonRPC、Hessian2 等官方支持的通信协议,如果以上协议都不能满足需求,还可以非常方便的通过定制方式接入自定义协议。如果你想在一个应用内使用多个协议,也可以非常容易的做到,比如一个接口使用 HTTP/2 通信,另一个接口使用 TCP 通信,一个应用内发布或调用多个使用不同协议的服务。
将任意通信协议无缝地接入 Dubbo 服务治理体系。Dubbo 体系下的所有通信协议,都可以享受到 Dubbo 的编程模型、服务发现、流量管控等优势。比如 gRPC over Dubbo 的模式,服务治理、编程 API 都能够零成本接入 Dubbo 体系。 兼容不同技术栈,业务系统混合使用不同的服务框架、RPC 框架。比如有些服务使用 gRPC 或者 Spring Cloud 开发,有些服务使用 Dubbo 框架开发,通过 Dubbo 的多协议支持可以很好的实现互通。 让协议迁移变的更简单。通过多协议、注册中心的协调,可以快速满足公司内协议迁移的需求。比如如从自研协议升级到 Dubbo 协议,Dubbo 协议自身升级,从 Dubbo 协议迁移到 gRPC,从 HTTP 迁移到 Dubbo 协议等。
官方接入的主流协议
Aliware
HTTP/2 (Triple)
支持 TLS 加密、Plaintext 明文数据传输 支持反压与限流 支持 Streaming 流式通信
在编程与通信模型上,Triple 协议支持如下模式:
消费端异步请求(Client Side Asynchronous Request-Response) 提供端异步执行(Server Side Asynchronous Request-Response) 消费端请求流(Request Streaming) 提供端响应流(Response Streaming) 双向流式通信(Bidirectional Streaming)
TCP (Dubbo2)
gRPC
REST
其他通信协议
Hessian2 Thrift JsonRPC
单端口多协议
Aliware
自 Dubbo 3.2 版本开始,Dubbo 提供了单个端口上的协议复用能力,通过调整 Protocol 配置即可实现。
比如在开启 HTTP/2 (Triple) 协议 或 gRPC 协议后,如我们同时启动端口复用,还可以在相同的端口上为服务增加 TCP (Dubbo2) 协议、Qos 协议的支持。这些所有流量的入口都在一个统一 port 端口, Dubbo 框架负责在端口之上识别不同的 RPC 协议,并进行处理器分发,从而实现单个端口上的协议复用。
实现原理
在服务的创建阶段,通过从 Config 层获取到服务导出的协议配置从而创建不同的 Protocol 对象进行导出。在导出的过程中,如果不是第一次创建端口复用的 Server,那么 Exchanger 会将 Protcol 层传递的数据保存到 Server,用于后续处理该协议类型的消息。 当客户端的消息传递过来后,首先会通过 Server 传递给 ProtocolDetector,如果完成了识别,那么就会标记该客户端为对应的协议。并通过 WireProtocol 配置对应的处理逻辑,最后交给 ChannelOperator 完成底层的 IO 框架和对应的 Dubbo 框架的处理逻辑的绑定。 以上的协议识别完成之后,Channel 已经确定了如何处理远程的客户端消息,通过对应的 ServerPipeline 进行处理即可(在处理的过程中也会根据配置信息决定消息的处理线程)。
使用场景
最常用的是用于服务发现。这允许应用程序通过网络发现服务,然后使用同一端口与它们通信,有助于降低网络通信的复杂性,并使其更易于管理。 可以用于负载平衡。这允许应用程序在多个远程服务或服务集群之间平衡负载,有助于提高服务的可扩展性、可靠性和可用性。 可以用于服务监控。这允许应用程序监视远程服务的运行状况,并在服务出现故障或变得不可用时发出警报,有助于确保服务的可用性并减少停机时间。
参考用例:
https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-port-unification
使用方式
关于 Dubbo 支持的配置方式 配置说明[2]
服务多协议导出
xml 配置
<dubbo:protocol name="dubbo" port="-1" ext-protocol="tri,"/><bean id="greetingService" class="org.apache.dubbo.demo.provider.GreetingServiceImpl"/><dubbo:service delay="5000" version="1.0.0" group="greeting" timeout="5000" interface="org.apache.dubbo.demo.GreetingService" ref="greetingService" protocol="dubbo"/>
API 配置
ProtocolConfig config = new ProtocolConfig(CommonConstants.TRIPLE, -1);config.setExtProtocol(CommonConstants.DUBBO+",");
yaml 配置
dubbo:application:name: dubbo-springboot-demo-providerprotocol:name: triport: -1ext-protocol: dubbo,
properties 配置
dubbo.protocol.name=tridubbo.protocol.ext-protocol=dubbo,dubbo.protocol.port=20880
Qos 接入
Qos 模块导入
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-qos</artifactId></dependency>
Qos 使用
直接调用命令
直接调用 telnet 支持的命令也可以完成识别,在用户不熟悉的情况下可以调用 help 指令完成识别
通过 telnet 命令建立连接之后,执行以下几个步骤:
使用 crtl + "]" 进入到 telnet 交互界面(telnet 默认的 escape character) 调用 "send ayt" 向服务端发送特殊识别字段(为 telnet 协议的一个特殊字段) 回车完成消息发送并进入到 dubbo 的交互界面
服务引用
ReferenceConfig<GreetingService> reference = new ReferenceConfig<>();reference.setInterface(GreetingService.class);reference.setListener("consumer");reference.setProtocol(this.protocol);// reference.setProtocol(CommonConstants.DUBBO);// reference.setProtocol(CommonConstants.TRIPLE);
总结
Aliware
对于微服务实践中经常会遇到的多协议通信的场景,Dubbo 不绑定协议的设计让用户可以灵活的选择通信协议,整个协议选择过程对上层 API 编码与运维治理完全透明;对于要在一个集群内同时处理多个协议的场景,Dubbo 的多协议支持也可以从容应对,而单端口的多协议复用支持进一步简化了这一过程。
相关链接: