高峰时客户端建连耗时从 20 毫秒涨到 3 秒,抓包看到 SYN 重传 3 次,服务端 netstat -s 里 SYN 到 drop 每分钟 400 个。日志里能对上时间点,这种反而好排。

半连接队列长度由 backlog 和 somaxconn 共同决定,队列满了新来的 SYN 直接丢弃。客户端只能按 1、2、4 秒退避重传,建连时间被拉长。这一点先确认清楚,后面就不用反复试。

netstat -s | grep -i listen
sysctl net.core.somaxconn
sysctl -w net.ipv4.tcp_max_syn_backlog=8192

围绕「SYN 队列溢出」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

改完顺手把文档补一句,省得下次自己重新推一遍。监控和日志的时间要对上,时区不一致会多绕很大一圈。

临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

处理上按这个顺序:先看 ListenOverflows 是否在涨;把 somaxconn 调到 4096;调大 tcp_max_syn_backlog;应用层尽快 accept 不要阻塞在业务里。

结果对不对很好判断,调大后 ListenOverflows 每分钟从 400 降到 0,建连 P99 回到 25 毫秒。

作者 9823189