Dubbo心跳机制

Dubbo 默认客户端和服务端都会发送心跳报文,用来保持 TCP 长连接状态.

在客户端和服务端,Dubbo 都会开启一个线程 循环扫描 并 检测连接是否超时.

在服务端发现超时则会主动关闭客户端连接.

在客户端发现超时则会主动重新创建连接.

默认心跳检测时间是 60 秒.

原理

provider 心跳默认是在 heartbeat(一分钟)内如果没有读消息或写消息,就会发送心跳请求消息,如果连着3次(180s)没有读消息,provider会关闭channel.

consumer 端的心跳默认是在 一分钟 内如果没有读消息或写消息,就会发送心跳请求消息,如果连着3次(三分钟)没有读消息,consumer会进行重连.

开启定时任务

provider 在启动 netty时,在 HeaderExchangeServer 的构造方法中,会通过 startHeatbeatTimer() 启动心跳定时任务.
consumer 在 HeaderExchangeClient 的构造方法里,同样通过 startHeatbeatTimer() 启动心跳定时任务.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void startHeatbeatTimer() {
// 停止原有定时任务
stopHeartbeatTimer();
// 发起新的定时任务
if (heartbeat > 0) {
heatbeatTimer = scheduled.scheduleWithFixedDelay(
new HeartBeatTask(new HeartBeatTask.ChannelProvider() {
public Collection<Channel> getChannels() {
return Collections.unmodifiableCollection(HeaderExchangeServer.this.getChannels());
}
}, heartbeat, heartbeatTimeout),
heartbeat, heartbeat, TimeUnit.MILLISECONDS);
}
}

HeartbeatHandler 会被串在请求和响应的处理链上.每当 received()收到消息时,会更新 ReadTimestamp,当 sent() 时 会更新 writeTimestamp.

HeartBeatTask 逻辑

1.遍历所有Channel.在服务端遍历的是所有客户端连接,客户端遍历的是所有服务端连接.
2.已经 closed 的 channel 不管.
3.最后读写的时间,只要有一个超过心跳间隔(默认 heartbeat 是一分钟),就创建并发送心跳 request.
4.检测 最后读的时间,若超过心跳超时时间(默认 heartbeatTimeout 是三分钟).若是 client 侧会 reconnect 重连,若是 server 侧会关闭客户端连接.