心跳检测
定义
心跳检测(Heartbeat)就是客户端定期给服务器发一个“我还活着”的小包(通常无业务意义)。
目的:检测客户端是否掉线;保持 NAT / 防火墙映射不过期(重要);让服务端维护在线状态、回收资源
心跳检测的模式
模式A:客户端主动发送 → 服务端被动检测(常用)
客户端每隔 N 秒 发送一个 ping
服务端收到后更新“最后活跃时间 last_active”
优点:简单稳定
缺点:服务器压力稍大(要记录时间)
模式 B:服务端主动发 → 客户端回 pong(WebSocket 常用)
Server: ping
Client: pong(自动回复)
优点:服务端主动性强,适合 WebSocket
缺点:需要维护 ping loop
心跳机制的核心思想
服务器维护每个连接的两个字段:
1 | conn.last_active // 最近一次接收消息或心跳的时间戳 |
每隔一段时间(例如 10 秒),服务器进行一次检查:
1 | if now - conn.last_active > timeout: |
注意事项
心跳不能太短(会炸服务器)
推荐值:WebSocket:20~40s;移动网络:30~60s;IoT:60~300s
太短会导致:CPU 天量 syscalls;网络风暴;电量快速下降(手机)
NAT超时问题(非常关键)
移动网络/路由器会在几分钟后关掉一个空闲 TCP,所以心跳保持连接是必须的。
和业务包一起更新 last_active
不是只有心跳才能更新活跃时间!
心跳包必须轻量(不要带大数据)
1 | PING |
高性能时间轮
处理百万连接时,不能对每个连接每秒循环检查。
解决方案:
使用时间轮(Time Wheel) O(1) 复杂度
Netty、ClickHouse、Kafka 都在用。
作用:每个连接插入到对应的时间槽;每秒只检查当前槽位的连接;不用遍历全部连接
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 JasmineRain's blog!
评论
