调第三方接口,curl 打十次偶尔报一次 Connection reset by peer,重试一下又正常。浏览器这边更直白,页面直接 ERR_CONNECTION_RESET,刷新就好。

RST 是 TCP 层的重置报文,和超时不是一回事。超时是等到没有响应,重置是对方明确告诉你这条连接作废。所以重点不是无脑重试,而是搞清楚 RST 是谁发的。

三种最常见的来源

  • 对端进程:服务重启、崩溃、连接被 accept 队列拒掉,内核替进程回一个 RST
  • 中间设备:防火墙、WAF、负载均衡按特征切断,典型是请求里带敏感词或 TLS 指纹不被识别
  • 空闲超时:NAT 表项和长连接保活的时间不一致,设备先清了表,下一个包到达直接回 RST

定位手法

先用 curl -v 看卡在哪一步。连接阶段就断,查端口和本机防火墙;TLS 握手之后断,WAF 或者协议版本协商的嫌疑大;请求发完等响应时断,多半是服务端超时主动关连接。再用 tcpdump 或 Wireshark 抓一次,重点看 RST 包的源地址和 TTL,TTL 比正常包小一截,基本可以判定是中间设备伪造的。

基础连通性也要确认:telnet 目标 443 能不能通,ping 大包看 MTU 是否触发分片。IPv6 链路 MTU 更小,大包被丢同样会表现成连接被重置,这类问题换 IPv4 试一次就能区分。

自己能改的那部分

客户端加重试和指数退避,能吞掉大部分偶发。服务端把 keepalive 调到比中间设备短,比如 60 秒,避免被清表。HTTP/2 在老旧设备上不稳,退回 HTTP/1.1 往往立刻见效。剩下的必须找运维看负载均衡日志,或者让对端查应用日志里有没有 accept 失败。

判断标准很朴素:只有你这台机器出现,查本地代理和网络;所有同事都偶发,问题就在链路或服务端那一侧。