Dubbo Remoting模块详解(下)

简介: Dubbo Remoting模块详解

ChannelHandler

注册在 Channel 上的消息处理器,接口的定义

image.png@SPI 注解表明该接口是一个扩展点。

有一类特殊的 ChannelHandler 专门负责实现编解码功能,从而实现字节数据与有意义的消息之间的转换,或是消息之间的相互转换

image.png

该接口也是一个扩展接口,encode()、decode() 被 @Adaptive 注解修饰,也就会生成适配器类,其中会根据 URL 中的 codec 值确定具体的扩展实现类。


DecodeResult 这个枚举是在处理 TCP 传输时粘包和拆包使用的,例如,当前能读取到的数据不足以构成一个消息时,就会使用 NEED_MORE_INPUT 枚举。


接下来看Client 和 RemotingServer 两个接口,分别抽象了客户端和服务端,两者都继承了 Channel、Resetable 等接口,也就是说两者都具备了读写数据能力。

Client、RemotingServer

都继承了 Endpoint,只是在语义上区分请求和响应职责,都具备发送数据能力。

image.png

Client 和 Server 的主要区别:

  • Client 只能关联一个 Channel
  • Server 可接收多个 Client 发起的 Channel 连接,所以在 RemotingServer 接口中定义了查询 Channel 的相关方法
  • image.png

Transporter

  • Dubbo 在 Client 和 Server 之上又封装了一层Transporter 接口
  • image.png
  • @SPI 注解扩展接口,默认使用“netty”扩展名

@Adaptive 注解表示动态生成适配器类,会先后根据“server”“transporter”的值确定 RemotingServer 的扩展实现类,先后根据“client”“transporter”的值确定 Client 接口的扩展实现。


几乎对每个支持的 NIO 库,都有接口实现

image.png

为什么要单独抽象出 Transporter层,不直接让上层使用 Netty?

正是利用了依赖反转原则(DIP),Netty、Mina、Grizzly 等 NIO 库对外接口和使用方式不同,若在上层直接依赖 Netty 或Grizzly,就依赖了具体的 NIO 库,而非依赖一个有传输能力的抽象,后续要切换实现的话,就需修改依赖和接入的相关代码。

有了 Transporter 层,就可通过 Dubbo SPI 修改使用的具体 Transporter 扩展实现,从而切换到不同 Client 和 RemotingServer 实现,切换底层 NIO 库,而无须修改代码。即使有更先进的 NIO 库出现,也只需开发相应的 dubbo-remoting-* 实现模块提供 Transporter、Client、RemotingServer 等核心接口的实现,即可接入,完全符合开放封闭原则。

Transporters

不是一个接口,而是门面类,封装了 Transporter 对象的创建(通过 Dubbo SPI)以及 ChannelHandler 的处理

public class Transporters {
    private Transporters() {
    ...
    public static RemotingServer bind(URL url, 
            ChannelHandler... handlers) throws RemotingException {
        ChannelHandler handler;
        if (handlers.length == 1) {
            handler = handlers[0];
        } else {
            handler = new ChannelHandlerDispatcher(handlers);
        }
        return getTransporter().bind(url, handler);
    }
    public static Client connect(URL url, ChannelHandler... handlers)
           throws RemotingException {
        ChannelHandler handler;
        if (handlers == null || handlers.length == 0) {
            handler = new ChannelHandlerAdapter();
        } else if (handlers.length == 1) {
            handler = handlers[0];
        } else { // ChannelHandlerDispatcher
            handler = new ChannelHandlerDispatcher(handlers);
        }
        return getTransporter().connect(url, handler);
    }
    public static Transporter getTransporter() {
        // 自动生成Transporter适配器并加载
        return ExtensionLoader.getExtensionLoader(Transporter.class)
            .getAdaptiveExtension();
    }
}

在创建 Client 和 RemotingServer 的时候,可指定多个 ChannelHandler 绑定到 Channel 来处理其中传输的数据。Transporters.connect() 方法和 bind() 方法中,会将多个 ChannelHandler 封装成一个 ChannelHandlerDispatcher 对象。


ChannelHandlerDispatcher 也是 ChannelHandler 接口的实现类之一,维护了一个 CopyOnWriteArraySet 集合,它所有的 ChannelHandler 接口实现都会调用其中每个 ChannelHandler 元素的相应方法。另外,ChannelHandlerDispatcher 还提供了增删该 ChannelHandler 集合的相关方法。


Endpoint 接口抽象了“端点”的概念,这是所有抽象接口的基础


上层使用方会通过 Transporters 门面类获取到 Transporter 的具体扩展实现,然后通过 Transporter 拿到相应的 Client 和 RemotingServer 实现,就可以建立(或接收)Channel 与远端进行交互


无论是 Client 还是 RemotingServer,都会使用 ChannelHandler 处理 Channel 中传输的数据,其中负责编解码的 ChannelHandler 被抽象出为 Codec2 接口。


Transporter 层整体结构图

image.png

参考

目录
相关文章
|
6月前
|
负载均衡 监控 Dubbo
【Dubbo 解析】模块分包解析
【1月更文挑战第11天】【Dubbo 解析】模块分包解析
【Dubbo 解析】模块分包解析
|
6月前
|
监控 负载均衡 Dubbo
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
104 0
|
运维 监控 Dubbo
Dubbo3 源码解读-宋小生-16:模块发布器发布服务全过程
> 完整电子书下载地址: https://developer.aliyun.com/ebook/7894 > Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双十一基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实
309 0
Dubbo3 源码解读-宋小生-16:模块发布器发布服务全过程
|
存储 运维 Dubbo
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
> Dubbo3 已经全面取代 HSF2 成为阿里的下一代服务框架,2022 双 11 基于 Dubbo3 首次实现了关键业务不停推、不降级的全面用户体验提升,从技术上,大幅提高研发与运维效率的同时地址推送等关键资源利用率提升超 40%,基于三位一体的开源中间件体系打造了阿里在云上的单元化最佳实践和统一标准,同时将规模化实践经验与技术创新贡献开源社区,极大的推动了开源技术与标准的发展。 > 本文
478 0
Dubbo3 源码解读-宋小生-3:框架,应用程序,模块领域模型Model对象的初始化
|
负载均衡 监控 Dubbo
Dubbo模块
cluster 集群容错、负载均衡 common 公共包 compatible 兼容,比如说包的改变、alibaba 变成 apache config 加载配置、提供统一的对外的配置 configcenter 配置中心、统一管理dubbo的配置 container 容器 filter 过滤 metadata 元数据 monitor 监控模块 plugin :auth、qos registry 注册中心 remoting 远程协议支持、netty、mina rpc rpc 通信协议的支持 serialization 序列化
117 0
|
存储 缓存 Dubbo
Java 200+ 面试题补充③ Dubbo 模块
Java 200+ 面试题补充③ Dubbo 模块
166 0
Java 200+ 面试题补充③ Dubbo 模块
|
编解码 Dubbo 应用服务中间件
一文讲明Dubbo Remoting模块(下)
一文讲明Dubbo Remoting模块(下)
87 0
一文讲明Dubbo Remoting模块(下)
|
编解码 Dubbo 网络协议
一文讲明Dubbo Remoting模块(上)
一文讲明Dubbo Remoting模块
99 0
一文讲明Dubbo Remoting模块(上)
|
6月前
|
Dubbo Java 应用服务中间件
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
微服务学习 | Springboot整合Dubbo+Nacos实现RPC调用
|
19天前
|
Dubbo Java 应用服务中间件
Spring Cloud Dubbo:微服务通信的高效解决方案
【10月更文挑战第15天】随着信息技术的发展,微服务架构成为企业应用开发的主流。Spring Cloud Dubbo结合了Dubbo的高性能RPC和Spring Cloud的生态系统,提供高效、稳定的微服务通信解决方案。它支持多种通信协议,具备服务注册与发现、负载均衡及容错机制,简化了服务调用的复杂性,使开发者能更专注于业务逻辑的实现。
44 2