Computer NetworkNotes

第 12 章:TCP 调优与疑难问题

zjc 于 2026-01-12 发布

这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 TCP 调优不是复制一份“高性能参数”。不同业务形态对应不同瓶颈:短连接服务要关注 TIME_WAIT 和队列,长肥管道要关注窗口和 BDP,高并发服务要关注 fd、内存和 IO 模型,容器和云环境还要关注 MTU、安全组和连接追踪表。

12.1 常用观测命令

ss -s
ss -ant
ss -i
ss -lnt
netstat -s
nstat -az
ip -s link
tc qdisc show

重点指标:

指标 含义
retrans 重传
rtt / rttvar 往返时延和抖动
cwnd 拥塞窗口
unacked 未确认数据
recv-q / send-q 队列
listen drops 监听队列丢弃
rx_dropped 网卡或内核丢包
conntrack full 连接追踪表满

12.2 文件描述符与端口

查看 fd 上限:

ulimit -n
cat /proc/sys/fs/file-max
cat /proc/sys/fs/file-nr

查看进程 fd:

ls /proc/<pid>/fd | wc -l

客户端临时端口:

sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_tw_reuse

端口耗尽原因:

  1. 频繁新建连接;
  2. 目标地址和端口单一;
  3. TIME_WAIT 未释放;
  4. 压测并发设计不合理;
  5. 连接池未生效。

优先使用长连接和多个目标 VIP,而不是盲目扩大端口范围。

12.3 缓冲区调优

自动调节:

sysctl net.ipv4.tcp_rmem
sysctl net.ipv4.tcp_wmem
sysctl net.core.rmem_max
sysctl net.core.wmem_max

典型格式:

min default max

判断是否需要调整:

  1. 吞吐远低于带宽;
  2. RTT 高;
  3. cwnd 或窗口受限;
  4. 丢包低;
  5. 大文件或流式传输场景。

不要在低 RTT 内网小请求服务上机械放大缓冲区,可能增加内存占用和排队。

12.4 队列与 backlog

应用监听 backlog:

listen(fd, backlog)

内核参数:

sysctl net.core.somaxconn
sysctl net.ipv4.tcp_max_syn_backlog

有效 accept 队列上限通常受 min(somaxconn, application backlog) 影响。

调优流程:

  1. 观察 ss -lnt
  2. 查看 listen overflow/drop;
  3. 判断应用 accept 是否慢;
  4. 增大 backlog;
  5. 优化 IO 和线程模型;
  6. 增加前置限流。

12.5 TIME_WAIT 治理

查看:

ss -ant state time-wait | wc -l

优先:

  1. 启用连接池;
  2. HTTP Keep-Alive;
  3. gRPC 长连接;
  4. 数据库连接复用;
  5. 降低无效重试频率。

Linux 客户端可在特定场景使用:

sysctl net.ipv4.tcp_tw_reuse

不要盲目设置 tcp_tw_recycle,该参数在 NAT 环境有严重问题,较新内核中已移除。

12.6 连接追踪与防火墙

有状态防火墙和 NAT 会维护 conntrack 表:

sysctl net.netfilter.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count

表满现象:

  1. 新建连接失败;
  2. 日志 nf_conntrack: table full;
  3. 丢包;
  4. 重启或清理后恢复;
  5. 高并发容器宿主机明显。

处理:

  1. 增大表容量;
  2. 缩短超时;
  3. 减少无意义短连接;
  4. 拆分流量到多宿主机;
  5. 使用无状态规则;
  6. 控制异常扫描。

12.7 MTU 与 MSS 问题

典型症状:

  1. 握手成功;
  2. 小包正常;
  3. 大包卡住;
  4. TLS 证书阶段失败;
  5. VPN、容器和 overlay 环境明显。

排查:

ip link
ping -M do -s 1472 <target>
tracepath <target>
tcpdump -i eth0 'icmp[icmptype] == icmp-unreach' -nn

处理:

  1. 统一路径 MTU;
  2. 调整 overlay 封装开销;
  3. 使用 MSS Clamp;
  4. 放行 PMTUD ICMP;
  5. 开启 TCP MTU probing 需评估。

12.8 长连接服务疑难问题

空闲断开

原因:

  1. LB 空闲超时;
  2. 防火墙会话超时;
  3. NAT 超时;
  4. 应用未处理半开连接;
  5. 服务端主动回收。

处理:

  1. 应用心跳间隔小于最低超时;
  2. 读空闲写事件触发;
  3. 客户端断线重连;
  4. 服务端推送心跳;
  5. 核对 LB 参数。

连接假活

现象:

  1. ESTABLISHED 存在;
  2. 对端已宕机;
  3. 发送后才发现失败。

处理:

  1. TCP keepalive;
  2. 应用层心跳;
  3. 业务级健康检查;
  4. 请求超时和快速失败;
  5. 连接池驱逐。

12.9 调优模板

高并发短连接服务:

增大 somaxconn 和应用 backlog
控制重试风暴
启用 SYN Cookie
监控 listen drops
评估 TIME_WAIT
前置限流

高吞吐长连接服务:

启用连接池和 Keep-Alive
评估 BDP 和缓冲区
选择拥塞算法
监控 cwnd / retrans / RTT
隔离批量流量

容器宿主机:

检查 fd 和 conntrack
统一 MTU
限制每 Pod 连接
监控 softnet
评估 IRQ 和队列

本章小结

TCP 调优必须从观测开始,区分监听队列、fd、端口、缓冲区、拥塞窗口、conntrack、MTU 和应用连接管理问题。短连接重点治理 TIME_WAIT 和重试,长连接重点治理心跳、窗口和吞吐。任何参数修改都应有监控、回滚和压测验证。

思考题

  1. ss -lnt 的 Recv-Q 和 Send-Q 在 LISTEN 状态表示什么?
  2. 临时端口耗尽时应优先做哪些改造?
  3. conntrack 表满会有什么表现?
  4. 为什么 tcp_tw_recycle 不适合 NAT 环境?
  5. 写一份高并发网关的 TCP 参数和监控清单。