2.22 HeaderExchangeServer
HeaderExchangeServer 是 Apache Dubbo 中用于服务端通信的核心实现类,负责管理服务器端的连接、消息交换和资源控制。

HeaderExchangeServer 是 RemotingServer 的装饰器,实现自 RemotingServer 接口的大部分方法都委托给了所修饰的 RemotingServer 对象。
- 核心职责
- 封装底层服务器: 包装 RemotingServer 实例,提供统一的服务端接口
- 连接管理: 管理客户端连接,监控连接状态
- 空闲检测: 实现连接空闲超时机制
- 优雅关闭: 支持带超时的服务器关闭流程
2.22.1 重要特性详解
private void startIdleCheckTask(URL url) {
if (!server.canHandleIdle()) {
AbstractTimerTask.ChannelProvider cp =
() -> unmodifiableCollection(HeaderExchangeServer.this.getChannels());
int closeTimeout = getCloseTimeout(url);
long closeTimeoutTick = calculateLeastDuration(closeTimeout);
this.closeTimer = new CloseTimerTask(cp, IDLE_CHECK_TIMER.get(), closeTimeoutTick, closeTimeout);
}
}
- 使用全局共享的 HashedWheelTimer 定时器进行空闲检测
- 当底层服务器无法自行处理空闲连接时,启动 CloseTimerTask
- 定期检查连接是否超时,自动关闭空闲连接
2.22.2 优雅关闭机制
✔️ 1. 基本关闭流程
@Override
public void close() {
if (!closed.compareAndSet(false, true)) {
return;
}
doClose();
server.close();
}
🚀 2. 带超时的关闭流程:
@Override
public void close(final int timeout) {
if (!closed.compareAndSet(false, true)) {
return;
}
startClose();
if (timeout > 0) {
final long start = System.currentTimeMillis();
if (getUrl().getParameter(Constants.CHANNEL_SEND_READONLYEVENT_KEY, true)) {
sendChannelReadOnlyEvent();
}
while (HeaderExchangeServer.this.isRunning() && System.currentTimeMillis() - start < (long) timeout) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
}
}
}
doClose();
server.close(timeout);
}
关键步骤:
- 设置关闭状态标志
- 发送只读事件通知客户端
- 等待现有连接处理完成或超时
- 执行资源清理
- 关闭底层服务器
2.22.3 只读事件通知
private void sendChannelReadOnlyEvent() {
Request request = new Request();
request.setEvent(READONLY_EVENT);
request.setTwoWay(false);
request.setVersion(Version.getProtocolVersion());
Collection<Channel> channels = getChannels();
for (Channel channel : channels) {
try {
if (channel.isConnected()) {
channel.send(request, getUrl().getParameter(Constants.CHANNEL_READONLYEVENT_SENT_KEY, true));
}
} catch (RemotingException e) {
if (closed.get() && e.getCause() instanceof ClosedChannelException) {
// ignore ClosedChannelException which means the connection has been closed.
continue;
}
logger.warn(TRANSPORT_FAILED_RESPONSE, "", "", "send cannot write message error.", e);
}
}
}
在服务器关闭前向所有连接的客户端发送只读事件,通知客户端服务器即将关闭,不再接受新请求。
2.22.4 连接管理
@Override
public Collection<ExchangeChannel> getExchangeChannels() {
Collection<ExchangeChannel> exchangeChannels = new ArrayList<>();
Collection<Channel> channels = server.getChannels();
if (CollectionUtils.isNotEmpty(channels)) {
for (Channel channel : channels) {
exchangeChannels.add(HeaderExchangeChannel.getOrAddChannel(channel));
}
}
return exchangeChannels;
}
- 统一管理所有客户端连接
- 为每个底层 Channel 创建或获取对应的 HeaderExchangeChannel
- 提供对所有连接的访问接口
2.22.5 核心设计要点
- 资源复用: 使用 GlobalResourceInitializer 确保定时器等资源在整个JVM中唯一
- 线程安全: 使用 AtomicBoolean 控制关闭状态,防止重复关闭
- 异常处理: 合理处理连接关闭过程中的各种异常情况
- 配置驱动: 通过URL参数灵活控制各种行为(如是否发送只读事件等)
- 平滑过渡: 在关闭过程中给客户端足够时间处理完正在进行的请求
HeaderExchangeServer 是Dubbo服务端通信的重要组件,通过封装底层服务器实现,提供了完善的连接管理、空闲检测和优雅关闭机制,确保服务端能够稳定可靠地运行和服务客户端请求。

3万+

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



