一句话定义:心跳(Heartbeat)是按固定间隔发送的一小段“我还在这儿”的信号,用来确认连接对端没有悄悄消失;保活(Keepalive)是这类机制的统称,也常特指操作系统或协议栈自带的探测开关。
为什么需要:TCP 连接本质上是两端各存一份状态,中间并没有一根实线。一方断电、进程被杀、手机切飞行模式时,来不及发 FIN/RST,对端就停在“半开连接”(half-open connection)里,以为还通着。更常见的是中间设备导致断开:NAT 网关、防火墙、负载均衡器为了省内存,会给空闲连接设一个闲置超时,到点就把表项悄悄删掉,两端都不知情,直到下一次真正发数据,才发现请求发出去没有任何回应。
打个比方:两个人打电话谈事,沉默太久你会“喂”一声,不是有话说,只想确认对方还在听。“喂”是心跳包,对方回“在”是心跳响应,“沉默多久该喂一声”就是保活间隔。
关键设计:心跳间隔必须小于链路上最短的那个闲置超时,否则无法续上连接。所以常见做法是几十秒一次,而不是等几小时。这样做也有代价:手机上一次心跳会唤醒无线电模块,耗电;服务端要为百万连接维护定时器,耗 CPU。于是有了自适应心跳:应用在前台时心跳频繁,退到后台后变稀疏。
几个容易混淆的概念:
| 概念 | 层次 | 回答的问题 | 典型形态 |
|---|---|---|---|
| 心跳 Heartbeat | 应用层 | 你的业务进程还活着吗 | WebSocket ping/pong、MQTT PINGREQ、SSE 注释行 |
| 保活 Keepalive | 传输层/系统层 | 对端主机还在网上吗 | TCP keepalive,闲置阈值以小时计 |
| 健康检查 Health check | 服务端侧 | 你能接流量吗 | 存活/就绪探针 |
| 轮询 Polling | 应用层 | 有新数据吗 | 定时请求接口 |
心跳不带业务语义;轮询是在索取数据;健康检查是第三方在确认服务能否接流量;TCP keepalive 由内核代为探测、粒度较粗、默认间隔很长,通常无法完全替代应用层心跳。
对从业者的意义:AI 应用里这一点最容易被忽视。长时间流式输出、Agent 跑几分钟工具调用、模型思考阶段迟迟不吐 token,中间的反向代理和网关很可能因为“一段时间没有字节流过”而中断连接,用户看到的是回答突然卡死。稳妥做法是在等待期间发送 SSE 注释行或协议级 ping,让连接上持续有流量;客户端同时配上断线重连与幂等重试。具体超时默认值各家不同,以官方页面为准。
