TCP 持续计时器:零窗口之后,是谁把代理IP 链路重新叫醒的

2026年09月01日

14 次

代理IP 链路上一条长连接突然卡住十几秒,抓包一看既没有丢包重传也没有连接断开,只有客户端每隔一会儿发一个 1 字节的小包。这个小包就是窗口探测,发它的计时器叫持续计时器。链路不是坏了,是接收方窗口曾经归零,而恢复通知在路途中丢了——持续计时器在兜底。

零窗口之后,发送方为什么不能自己继续发

TCP 的流量控制依赖接收窗口:接收方在确认报文里告诉发送方”我还能收多少字节”,发送方只在窗口范围内发数据。上一篇文章讲过零窗口——接收方窗口归零后发送方停止发送,等接收方腾出空间后发一个窗口更新 ACK 通知恢复。问题在于这个窗口更新 ACK 也会丢:它本身不带数据,接收方不会因为”发送方没回应”而重发,因为 TCP 只有收到数据才确认,收不到数据就永远不再发第二次窗口更新。

于是两边都进入等待:发送方等窗口更新,接收方以为窗口更新早就到了。如果没有兜底机制,这条连接会一直卡到天荒地老,任何一方都察觉不到异常。

TCP 的解法是持续计时器:发送方发现窗口归零后,启动一个 persist timer,到点就主动发一个 1 字节的窗口探测包(window probe)。接收方收到探测包后必须回复一个 ACK,即使窗口还是零也要回——这个 ACK 里就带着最新的窗口值。窗口恢复了,发送方立刻接着发;窗口没恢复,就按退避节奏继续探测。

对比项 持续计时器 Persist 重传超时 RTO Keepalive 探活
要解决什么 窗口恢复通知丢了 数据确认丢了 对端静默消失
发送什么 1 字节窗口探测 重发原数据段 空探针包
探测频率 退避增长 指数退避 固定间隔
代理链路上的表现 周期性 1 字节小包 重复数据段 空闲期探针

代理IP 链路为什么更容易被持续计时器”困住”

代理IP 链路把一条连接拆成两段,每段各有自己的发送窗口和持续计时器,但窗口更新 ACK 的传递路径变长了:本机到代理、代理到目标站两段连接在代理处背靠背转发,中间任何一端的接收缓冲被占满,窗口就会归零,而窗口更新 ACK 要穿过代理的转发队列才能到达对端。转发队列一积压,窗口更新 ACK 就被延迟;延迟超过发送方的探测节奏,持续计时器就会把 1 字节探测包发出来。

所以走代理IP 后,抓包看到成串的 1 字节小包并不罕见。判断是不是它在作怪,看三点:探测包的间隔是否在退避增长(5 秒、10 秒、20 秒翻上去);两次探测之间是否有大量已确认数据积压;窗口更新 ACK 到达后连接是否立刻恢复传输。三者都对上,基本就是窗口更新在代理转发队列里被拖住了。

处置方向:优先看代理转发缓冲与出口拥塞,而不是怀疑连接断了;代理IP 链路上的大流量长连接业务(同步、备份、推送)对窗口恢复最敏感,把这类流量安排到稳定出口、错开高峰,能明显减少”卡住十几秒又自己好”的现象。

零窗口不是终点,窗口更新丢失才是真正的坑——持续计时器就是 TCP 为这个坑兜的底,代理IP 链路的两段连接各有各的计时器,任何一段被拖住都会表现为莫名其妙的停顿。

相关咨询请联系QQ/微信:157069302