定义

心跳检测(Heartbeat)就是客户端定期给服务器发一个“我还活着”的小包(通常无业务意义)。

目的:检测客户端是否掉线;保持 NAT / 防火墙映射不过期(重要);让服务端维护在线状态、回收资源

心跳检测的模式

模式A:客户端主动发送 → 服务端被动检测(常用)

客户端每隔 N 秒 发送一个 ping
服务端收到后更新“最后活跃时间 last_active”

优点:简单稳定
缺点:服务器压力稍大(要记录时间)

模式 B:服务端主动发 → 客户端回 pong(WebSocket 常用)

Server: ping
Client: pong(自动回复)

优点:服务端主动性强,适合 WebSocket
缺点:需要维护 ping loop

心跳机制的核心思想

服务器维护每个连接的两个字段:

1
2
conn.last_active   // 最近一次接收消息或心跳的时间戳
conn.timeout // 超时时间,例如 60s

每隔一段时间(例如 10 秒),服务器进行一次检查:

1
2
if now - conn.last_active > timeout:
close(conn)

注意事项

心跳不能太短(会炸服务器)

推荐值:WebSocket:20~40s;移动网络:30~60s;IoT:60~300s

太短会导致:CPU 天量 syscalls;网络风暴;电量快速下降(手机)

NAT超时问题(非常关键)

移动网络/路由器会在几分钟后关掉一个空闲 TCP,所以心跳保持连接是必须的。

和业务包一起更新 last_active

不是只有心跳才能更新活跃时间!

心跳包必须轻量(不要带大数据)

1
2
3
PING
PONG
{}

高性能时间轮

处理百万连接时,不能对每个连接每秒循环检查。

解决方案:
使用时间轮(Time Wheel) O(1) 复杂度
Netty、ClickHouse、Kafka 都在用。

作用:每个连接插入到对应的时间槽;每秒只检查当前槽位的连接;不用遍历全部连接