CRS

机柜 / U39

协议 · 2026-06-18 · 9 分钟

三次握手里的那次超时

客户端报 connection timed out。服务端 access log 是空的。两边都很委屈:我没收到,所以我没做错。

三次握手里最常见的失踪者是 SYN。它可能死在客户端的 iptables,中间那台 stateful 防火墙的半开表,或者服务端的 syn backlog。你在应用层抓不到它,因为它还没变成连接。

把失踪地点写下来

  1. 客户端:ss -tne 看有没有 SYN-SENT 堆着。
  2. 路径:traceroute -n -T -p 443 走 TCP,不要用 ICMP 自欺。
  3. 服务端:ss -lnt 的 Send-Q,以及 nstat -az TcpExtListenOverflows。
  4. 两端同时 tcpdump 'tcp[tcpflags] & (tcp-syn) != 0'。只在一边出现的 SYN,就是那一跳的口供。

Linux 的 SYN 重传默认偏温柔。第一次超时大约 1s,然后 2s、4s。用户以为「卡了」,内核以为「还在努力」。把 tcp_syn_retries 调小,失败会更快;不修丢失,只是让失败更诚实。

tcpdump -ni eth0 'tcp[tcpflags] & (tcp-syn) != 0 and port 443'

握手成功但首字节很慢,是另一篇笔记。那是应用没 accept,或者 TLS 在等一张远方的 CRL。先确认 SYN-ACK 回来了,再去怪你的程序。

SYN 丢了不可怕。可怕的是你只用应用日志去找它。

U39 · 棕线,协议。