文章目录
2.21 HeaderExchangeClient
HeaderExchangeClient 是 Apache Dubbo 框架中的一个关键组件,它实现了 ExchangeClient 接口,负责客户端的通信功能,并支持心跳检测和自动重连机制。
2.21.1 主要职责与作用
- 封装底层Client:HeaderExchangeClient 封装了实际的 Client 实例,通过组合模式对外提供统一的客户端交互接口。
- 消息交换层抽象:通过内部的 HeaderExchangeChannel 提供基于请求/响应模型的消息交换能力。
- 连接管理:包括连接状态维护、心跳检测以及断线重连等功能。
2.21.2 核心属性与初始化
private final Client client; // 被修饰的 Client 对象。HeaderExchangeClient 中对 Client 接口的实现,都会委托给该对象进行处理。
private final ExchangeChannel channel; // Client 与服务端建立的连接,HeaderExchangeChannel 也是一个装饰器,在前面我们已经详细介绍过了,这里就不再展开介绍。HeaderExchangeClient 中对 ExchangeChannel 接口的实现,都会委托给该对象进行处理。
public static GlobalResourceInitializer<HashedWheelTimer> IDLE_CHECK_TIMER = ...;
private ReconnectTimerTask reconnectTimerTask;
private HeartbeatTimerTask heartBeatTimerTask;
private final int idleTimeout;
✅ 初始化过程
- 在构造函数中接收并保存传入的 Client 对象;
- 创建 HeaderExchangeChannel 来处理具体的请求/响应逻辑;
- 如果启用定时任务,则根据 URL 配置启动心跳检测和重连任务;
- 计算空闲超时时间(idleTimeout)用于后续判断是否需要触发重连或关闭连接;
2.21.3 心跳检测与重连机制
当客户端不支持自己处理空闲事件时(即 !client.canHandleIdle() 成立),会创建心跳任务:
private void startHeartBeatTask(URL url) {
if (!client.canHandleIdle()) {
int heartbeat = getHeartbeat(url);
long heartbeatTick = calculateLeastDuration(heartbeat);
heartBeatTimerTask = new HeartbeatTimerTask(
() -> Collections.singleton(this),
IDLE_CHECK_TIMER.get(),
heartbeatTick,
heartbeat);
}
}
2.21.4 自动重连任务 (ReconnectTimerTask)
private void startReconnectTask(URL url) {
if (shouldReconnect(url)) {
long heartbeatTimeoutTick = calculateLeastDuration(idleTimeout);
reconnectTimerTask = new ReconnectTimerTask(
() -> Collections.singleton(this),
IDLE_CHECK_TIMER.get(),
calculateReconnectDuration(url, heartbeatTimeoutTick),
idleTimeout);
}
}
这两个任务都依赖于共享的 HashedWheelTimer 定时器实例,该定时器是全局唯一的资源,在整个 JVM 生命周期内只会被初始化一次。
2.21.5 连接状态检查
isConnected() 方法不仅检查底层通道的状态,还会考虑最近读取的时间戳来决定当前连接是否仍然活跃
@Override
public boolean isConnected() {
if (channel.isConnected()) {
if (idleTimeout <= 0) {
return true;
}
Long lastRead = (Long) channel.getAttribute(HeartbeatHandler.KEY_READ_TIMESTAMP);
Long now = System.currentTimeMillis();
return lastRead == null || now - lastRead < idleTimeout;
}
return false;
}
这个实现确保即使物理连接未断开,但如果长时间没有数据往来也会被视为非活跃连接。
2.21.6 资源清理
在关闭过程中,除了调用底层 channel.close() 外,还需要取消已注册的心跳及重连任务:
private void doClose() {
if (heartBeatTimerTask != null) {
heartBeatTimerTask.cancel();
heartBeatTimerTask = null;
}
if (reconnectTimerTask != null) {
reconnectTimerTask.cancel();
reconnectTimerTask = null;
}
}
HeaderExchangeClient 类作为 Dubbo 中客户端通信的核心实现之一,提供了完整的网络通信生命周期管理,包括但不限于建立连接、发送接收数据、维持连接健康状态以及优雅地释放资源。其设计充分体现了面向对象编程中的封装性和可扩展性原则,使得上层应用能够更加专注于业务逻辑而非底层细节

802

被折叠的 条评论
为什么被折叠?



