【048】Dubbo3从0到1系列之HeaderExchangeChannel

2.20 HeaderExchangeChannel

HeaderExchangeChannel 是 Dubbo 中 ExchangeChannel 接口的一个具体实现,它提供了基于头部(header)的请求-响应交换机制。这是 Dubbo 远程通信的核心组件之一。

本身是 Channel 的装饰器,封装了一个 Channel 对象,其 send() 方法和 request() 方法的实现都是依赖底层修饰的这个 Channel 对象实现的。

2.20.1 核心字段

channel: 底层的 Channel 对象,用于实际的数据传输
shutdownTimeout: 关闭通道时的超时时间
closed: 通道关闭状态的标识符
CHANNEL_KEY: 用于在底层通道属性中存储 HeaderExchangeChannel 实例的键值

2.20.2 构建方法和工厂方法

🚀 构建方法

HeaderExchangeChannel(Channel channel)
  • 私有构造方法,只能通过静态工厂方法创建实例
  • 验证传入的 channel 不为空
  • 从 channel 的 URL 中获取关闭超时配置

⬆️ 静态工厂方法

getOrAddChannel(Channel ch):
	获取或创建 HeaderExchangeChannel 实例
	使用属性机制避免重复创建
	只有在通道连接状态下才会缓存实例
removeChannelIfDisconnected(Channel ch):
	当通道断开连接时移除缓存的 HeaderExchangeChannel
removeChannel(Channel ch):
	强制移除通道关联的 HeaderExchangeChannel

2.20.3 核心方法

✅ 核心方法实现

@Override
public void send(Object message) throws RemotingException
@Override
public void send(Object message, boolean sent) throws RemotingException
  • 支持发送 Request、Response 或普通消息
  • 对于非 Request/Response 消息,会自动包装成单向 Request
  • 检查通道关闭状态,防止向已关闭通道发送消息

✅ 请求方法

HeaderExchangeChannel 实现了 ExchangeChannel 的四个 request 方法:
request(Object request):
	使用默认超时时间发送请求
request(Object request, int timeout):
	指定超时时间发送请求
request(Object request, ExecutorService executor):
	使用指定执行器发送请求
request(Object request, int timeout, ExecutorService executor):
	最完整的请求方法,支持自定义超时和执行器

📴 关闭方法

关闭方法 (close)
close():
	立即关闭通道
	优雅地处理未完成的请求
	关闭底层通道
close(int timeout):
	带超时的优雅关闭
	等待指定时间内未完成的请求处理完毕
	超时后强制关闭

📌 其它接口方法实现

地址获取: getLocalAddress(), getRemoteAddress()
状态检查: isConnected(), isClosed()
URL 和属性管理: getUrl(), getAttribute(), setAttribute() 等
处理器获取: getChannelHandler(), getExchangeHandler()

request方法源码实现:

@Override
public CompletableFuture<Object> request(Object request, int timeout, ExecutorService executor)
    throws RemotingException {
    if (closed) {
        throw new RemotingException(
            this.getLocalAddress(),
            null,
            "Failed to send request " + request + ", cause: The channel " + this + " is closed!");
    }
    Request req;
    if (request instanceof Request) {
        req = (Request) request;
    } else {
        // create request.
        req = new Request();
        req.setVersion(Version.getProtocolVersion());
        req.setTwoWay(true);
        req.setData(request);
    }
    DefaultFuture future = DefaultFuture.newFuture(channel, req, timeout, executor);
    try {
        channel.send(req);
    } catch (RemotingException e) {
        future.cancel();
        throw e;
    }
    return future;
}

在这里插入图片描述

注意意这里的 request() 方法,它返回的是一个 DefaultFuture 对象。io.netty.channel.Channel 的 send() 方法会返回一个 ChannelFuture 方法,表示此次发送操作是否完成,而这里的 DefaultFuture 就表示此次请求 - 响应是否完成,也就是说,要收到响应为 Future 才算完成

2.20.4 DefaultFuture

DefaultFuture 是 Dubbo 远程通信中用于管理异步请求-响应的核心组件,它继承自 CompletableFuture,提供了请求超时检测、响应处理、资源清理等功能。

✅ 1. 核心静态字段

CHANNELS: 存储正在进行中的通道映射,key为请求ID,value为对应的 Channel
FUTURES: 存储正在进行中的请求Future,key为请求ID,value为对应的 DefaultFuture
TIME_OUT_TIMER: 全局定时器资源,用于超时检测,使用 HashedWheelTimer 实现
logger: 日志记录器

📌 2. 实例字段

id: 请求的唯一标识符,与 Request 的ID一致
channel: 关联的通信通道
request: 对应的请求对象
timeout: 超时时间(毫秒)
start: 请求开始时间戳
sent: 请求发送时间戳
timeoutCheckTask: 超时检查任务
executor: 用于处理响应的执行器

🗂️ 3. 核心方法详解

  • 构造方法
private DefaultFuture(Channel channel, Request request, int timeout)
// 方法说明
// 私有构造方法,只能通过 newFuture 静态方法创建实例
// 初始化请求ID、通道、请求对象和超时时间
// 将新创建的Future注册到 FUTURES 和 CHANNELS 映射中
  • Future创建方法
public static DefaultFuture newFuture(Channel channel, Request request, int timeout, ExecutorService executor)
// 创建新的 DefaultFuture 实例
// 设置执行器
// 启动超时检查任务
// 返回创建的Future对象
  • 超时检查机制
private static void timeoutCheck(DefaultFuture future)
  • TimeoutCheckTask 内部类
private static class TimeoutCheckTask implements TimerTask{ ... }
// 实现定时器任务接口
// 在超时发生时创建相应的超时响应
// 根据请求是否已发送确定超时类型(客户端超时或服务端超时)
// 通过执行器异步通知超时事件

  • 响应处理方法
public static void received(Channel channel, Response response, boolean timeout)

// 处理接收到的响应
// 从 FUTURES 中移除对应的Future
// 取消超时检查任务(非超时响应)
// 调用 doReceived 处理响应结果
// 清理通道映射

🎲 4. 设计特点

  1. 资源管理
  • 使用 GlobalResourceInitializer 管理全局定时器资源
  • 通过静态映射表跟踪所有正在进行的请求
  • 自动清理完成或取消的请求资源
  1. 超时处理
  • 基于 HashedWheelTimer 的高效定时器实现
  • 区分客户端超时和服务端超时
  • 支持自定义超时时间和执行器
  1. 异常处理
  • 完善的状态码体系对应不同类型的异常
  • 详细的超时信息记录和日志输出
  • 优雅的资源清理机制
  1. 线程安全
  • 使用 ConcurrentHashMap 存储共享状态
  • volatile 关键字保证可见性
  • 同步块保护关键操作

📴 5. 工作流程

  • 请求发起: 通过 newFuture 创建 DefaultFuture 实例并启动超时检测
  • 请求发送: 调用 sent 方法记录发送时间
  • 等待响应: 客户端通过 CompletableFuture API 等待结果
  • 响应处理: 收到响应后通过 received 方法完成Future
  • 超时处理: 超时发生时自动创建超时响应并完成Future
  • 资源清理: Future完成后自动清理相关资

🔑 6. 关键创新点

  • 双映射跟踪: 同时使用请求ID到Future和请求ID到Channel的映射,提高查找效率
  • 精确超时分类: 根据请求是否已发送区分客户端和服务端超时
  • 灵活执行器支持: 支持自定义执行器处理响应回调
  • 优雅关闭: 通道关闭时等待未完成请求或提供适当响应
  • 详细诊断信息: 提供丰富的超时和错误信息用于问题排查
  • DefaultFuture 是 Dubbo 异步通信机制的核心,为上层应用提供了透明的请求-响应语义和完善的超时控制机制。

2.20.5 设计特点

  • 装饰器模式: 包装底层 Channel,添加请求-响应语义
  • 线程安全: 通过 volatile 关键字保证 closed 状态的可见性
  • 资源管理: 通过属性机制避免重复创建实例
  • 优雅关闭: 支持等待未完成请求处理完毕后再关闭
  • 异常处理: 完善的日志记录和异常处理机制

2.20.6 工作原理

HeaderExchangeChannel 通过以下机制实现请求-响应通信:

  • 请求包装: 将业务数据包装成 Request 对象
  • Future 跟踪: 使用 DefaultFuture 跟踪每个请求的响应
  • ID 匹配: 通过请求 ID 将响应与对应的请求进行匹配
  • 异步回调: 使用 CompletableFuture 提供异步响应处理能力
  • 生命周期管理: 通过状态管理和优雅关闭确保资源正确释放
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值