2044 字
约 6 分钟
6
S02-J01 · TCP 排障与调优:抓包、重传、TIME_WAIT 与内核参数

适用读者:线上出现"偶发超时""吞吐上不去""连接数异常"时要独立定位的人。
前置:S02-B03、S02-B04。
实测环境:Ubuntu 24.04.1 / Linux 6.8 / iproute2(ss、nstat、tc);实测日期 2026-11-05。
覆盖旧文:—(E 驱动;B03/B04 的机制在此工程化)
覆盖扩展:E-S02-021(排障流程)、E-S02-022(内核参数)。
上一篇:S02-X01 · 面试问答速查:操作系统 / 计算机网络 / 网络编程
下一篇:S02-J02 · TLS 深水区。


1. 一句话结论

TCP 排障的全部要点:先分层定位(应用 / 内核 / 网络),再用"计数器"而不是"感觉"说话。

层 观察手段 典型异常
应用 日志耗时、线程栈 业务慢、锁等待
内核协议栈 ss -ti、nstat 重传、RTT 抖动、窗口为 0
网络 ping/tc/丢包计数 丢包、延迟、MTU

2. 排障 SOP:六步

第 1 步:确认是"连不上"还是"连上了慢"

ss -tan | awk 'NR>1{print $1}' | sort | uniq -c | sort -rn
  • 大量 SYN-SENT → 握手无响应(对端不可达/防火墙丢弃)
  • 大量 TIME-WAIT → 短连接过多(B03 §4)
  • 大量 CLOSE-WAIT → 应用没有 close(代码泄漏 fd,这是最常见的一类)

第 2 步:看单条连接的真实状态

ss -ti state established

实测样例:

cubic wscale:7,7 rto:204 rtt:3.145/0.924 ... cwnd:10 ... bytes_sent:245816 ... retrans:0
字段 含义 异常判据
rtt 平滑 RTT / 偏差 抖动大 → 路由或排队
rto 重传超时 明显大于 RTT 的 3 倍 → 可能已有超时
cwnd 拥塞窗口(MSS 数) 长期很小 → 被判拥塞
retrans 该连接重传次数 > 0 就要关注;占比 > 1% 必须查
send-q 发送队列积压 持续增长 → 对端不收或带宽不足

第 3 步:看全系统计数器(比抓包快得多)

nstat -az | grep -E "TcpRetransSegs|TcpExtTCPLostRetransmit|TcpExtListenOverflows|TcpExtListenDrops"
计数器 含义 增长说明
TcpRetransSegs 重传段总数 网络丢包或拥塞
TcpExtTCPLostRetransmit 重传又丢 链路质量差
TcpExtListenOverflows accept 队列溢出 应用 accept 太慢(不是网络问题!)
TcpExtListenDrops 因队列满丢弃的 SYN 同上,或 SYN Flood

实测对比(B04 的丢包实验里):

重传计数(前)=274880 → 重传计数(后)=274947   # 20% 丢包下传 12.5 MB,新增 67 段重传

第 4 步:确认瓶颈是"延迟"还是"带宽"

# 注入/复现延迟:只在测试环境做
sudo tc qdisc add dev lo root netem delay 100ms
# 观察往返

实测:注入 100 ms 延迟后,单次往返 201 ms(≈ 2×100 ms)。

判据:延迟高但吞吐正常 → 交互型业务(登录、页面)会卡;带宽满但延迟正常 → 批量传输瓶颈。

第 5 步:需要抓包时(不是第一步)

抓包最贵(CPU、磁盘、权限),只在第 1–4 步无法定论时用:

# 只在测试/受控环境;生产优先用 ss/nstat
tcpdump -i eth0 -nn 'tcp port 8080 and tcp[tcpflags] & tcp-syn != 0' -c 20

容器内常见限制:没有 CAP_NET_RAW → 抓不到包。替代方案:ss -ti(内核已统计)、nstat(计数器)、应用侧埋点。

第 6 步:改参数前先算清代价

见 §4。


3. 三类问题的标准处置

3.1 "偶发超时"(最常见的工单)

① nstat 看 TcpRetransSegs 是否有增量 → 有:网络/拥塞
② ss -ti 看 rtt 抖动 → 大:路由或中间设备排队
③ 看 TcpExtListenOverflows → 增长:应用 accept 慢(查线程池/GC)
④ 都没有 → 看应用侧耗时(B 系列之外,见 S16 可观测性)

3.2 "吞吐上不去"

检查 命令 结论
窗口是否放大 ss -ti 的 wscale 未启用 → 长肥管道受限(B04 §3.5)
是否有丢包 nstat 重传 有 → 拥塞控制降速(B04 §2 实测 1,700 倍差距)
单连接还是多连接 ss -s 单连接跑满需要大窗口;多连接要算总带宽

3.3 "连接数异常"

ss -s                  # 总览:estab / timewait / closed
ss -tan state close-wait | wc -l     # 应用未关闭的连接
cat /proc/sys/fs/file-max; ulimit -n # fd 上限

CLOSE-WAIT 堆积 = 应用 bug(没 close),不是内核问题。这一条能省掉很多无效排查。


4. 内核参数:改之前先知道自己在改什么

实测本机默认值:

$ cat /proc/sys/net/core/somaxconn
4096
$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
512
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
$ cat /proc/sys/net/ipv4/tcp_fin_timeout
60
$ ulimit -n
524288
参数 作用 调大的收益 代价/风险
somaxconn accept 队列上限 抗突发连接 内存;不能解决应用慢
tcp_max_syn_backlog 半连接队列上限 抗 SYN 突发 内存;SYN Flood 需配 syncookies
tcp_keepalive_time 空闲多久开始探测 更快清理死连接 探测流量;仍不能替代应用心跳(B08)
tcp_fin_timeout FIN_WAIT_2 超时 更快回收 太短会导致异常关闭
tcp_tw_reuse 复用 TIME_WAIT(出向) 缓解客户端端口耗尽 对服务端被动关闭无效
tcp_tw_recycle — — 已移除,禁止使用(NAT 下故障)
net.core.rmem_max/wmem_max 缓冲上限 高 BDP 链路吞吐 内存

纪律:

  1. 一次只改一个参数,记基线(nstat 前后对比)。
  2. 先改 somaxconn 与 backlog(低风险),最后才碰内存类参数。
  3. 不要照抄"网上的万能调优脚本"——每条参数都对应特定故障。

5. 一个完整的排障记录模板

## 现象
14:20–14:35 期间,订单服务调用支付网关 P99 从 120ms 涨到 3.2s,错误率 0.8%

## 分层定位
- 应用层:支付网关自身 RT 正常(其监控显示 P99 130ms)
- 内核层:ss -ti 显示 rtt 3ms → 180ms,retrans 12;nstat TcpRetransSegs 增量 4.2 万
- 网络层:同机房其他服务正常;仅本机到该网关的链路异常

## 结论
本机所在宿主网络出现丢包(疑似上联拥塞),TCP 触发大量重传 + cwnd 收缩

## 处置
切换出口网卡/联系网络组;应用侧加重试(幂等)+ 超时

## 验证
nstat 重传增量归零;P99 回落至 130ms

模板的价值:把"猜测"变成"证据链",复盘时别人能照着复核。


6. 五个误区

误区 真相
"超时就是网络问题" 一半以上是应用侧(GC、锁、连接池耗尽)
"调大 backlog 就能抗高并发" 应用 accept 慢的话,队列只会积压更多
"抓包最权威" 生产抓包成本高;ss/nstat 往往够用
"重传一定是网络坏" 也可能是接收窗口为 0、MTU 不匹配
"调参万能" 参数只影响"忍多久",不解决根因

7. 自检

  1. CLOSE-WAIT 堆积说明什么?该查哪一侧?
  2. TcpExtListenOverflows 增长时,第一反应应该是什么?
  3. 为什么 tcp_tw_reuse 对"服务端主动关闭"无效?
  4. 注入 100 ms 延迟,为什么往返是 200 ms?
  5. nstat 与 tcpdump 各自的适用边界是什么?

8. 下一篇

S02-J02 · TLS 深水区:握手细节、证书链、双向认证与常见错误

网络层排障之后,下一个高频故障域是 TLS:SSLHandshakeException 到底卡在哪、自签 CA 怎么搭、mTLS 怎么配。下一篇用真实生成的 CA 与服务器证书复现"链不完整"和"主机名不匹配"两类错误。


本篇属于系列《S02 · 计算机与网络基础》。扩展点 E-S02-021/022。内核参数、netem 延迟、重传计数均为 2026-11-05 实测。

S02-J01 · TCP 排障与调优:抓包、重传、TIME_WAIT 与内核参数
https://www.clxhxhhr.top/posts/5192/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。