Linux 网络参数配置不当的性能问题

1次阅读

TCP性能瓶颈主因四大内核参数配置不当:tcp_rmem/wmem过小限制吞吐;somaxconn.netdev_max_backlog不足致连接拒绝;route.max_size过小引发路由GC毛刺;ip_local_port_range过窄加剧TIME_WaiT积。

Linux 网络参数配置不当的性能问题

net.ipv4.tcp_rmem 和 tcp_wmem 设置过小导致吞吐骤降

tcp_rmem(接收缓冲区)或 tcp_wmem(发送缓冲区)的最小值或默认值设得太低(比如仍用内核默认的 4K/16K/64K),在高延迟、高带宽网络(如跨机房 10G 链路)中,TCP 窗口无法有效扩展,实际吞吐会被限制在几 MB/s,远低于链路能力。

实操建议:

  • sysctl -w net.ipv4.tcp_rmem="4096 262144 16777216" 将 min/default/max 分别设为 4K/256K/16M;tcp_wmem 同理,但 max 可设为 8M~16M(避免过度占用内存)
  • 确认应用是否启用 TCP_winDOW_CLAMP 或手动调用 setsockopt(..., SO_RCVBUF/SO_SNDBUF, ...) —— 这些会覆盖系统级设置,需一并检查
  • 修改后必须通过 ss -i 查看单连接的实际 rcv_wndsnd_wnd,不能只信 sysctl 输出

net.core.somaxconn 和 net.core.netdev_max_backlog 不足引发连接拒绝

短连接高峰时(如 Web API 突发请求),若 somaxconn(listen backlog)仍为旧默认值 128,或 netdev_max_backlog(软中断队列)太小,新 SYN 包会在内核协议被静默丢弃,客户端看到的是 “Connection refused” 或超时,而非 RST。

实操建议:

  • somaxconn 应 ≥ 应用层 listen() 调用传入的 backlog 参数(如 nginxlisten ... backlog=4096),建议统一设为 65535
  • netdev_max_backlog 需 ≥ 单网卡每秒处理包数 × 0.1s(典型值 5000~10000),否则软中断来不及处理,包在 NIC 队列溢出前就被丢弃
  • 检查是否启用了 net.ipv4.tcp_syncookies=1:它虽能缓解 SYN Flood,但在合法高并发下会导致部分连接重传增加,应优先调大 net.ipv4.tcp_max_syn_backlog(设为 65535)并关闭 syncookies

net.ipv4.route.max_size 过小触发路由缓存强制淘汰

在容器化环境或大量 Pod/Service 场景下,主机路由表条目常达数千甚至上万。若 route.max_size 保持默认(通常 2048 或 8192),内核会频繁触发 ip_rt_gc_interval 扫描和强制 GC,造成周期性网络延迟毛刺,ip -route show 中可见大量临时路由反复增删。

实操建议:

  • ip route | wc -l 统计当前路由数,若 > 70% 的 route.max_size 值,就该扩容;生产环境建议设为 524288(512K)
  • 注意该参数是全局限制,不区分 unicast/multicast,且修改后仅对新增路由生效,已有条目不会被清理
  • 搭配 net.ipv4.route.gc_thresh* 系列参数同步调整(如 gc_thresh1 设为 max_size 的 1/4),否则 GC 逻辑可能失效

net.ipv4.ip_local_port_range 设置不当加剧 TIME_WAIT 占用

ip_local_port_range 过窄(如默认 32768–60999,仅约 28K 端口),在短连接密集型服务(如 http client 频繁调用下游)中,端口耗尽速度加快,大量连接卡在 TIME_WAIT 状态,表现为 ss -tan state time-wait | wc -l 持续 > 20K,后续新建连接失败。

实操建议:

  • 将范围扩至 1024 65535(避开 1–1023 特权端口即可),可用 sysctl -w net.ipv4.ip_local_port_range="1024 65535"
  • 不建议盲目开启 net.ipv4.tcp_tw_reuse=1:它仅对 client 端有效,且要求时间戳(tcp_timestamps=1)启用,而某些中间设备会干扰时间戳,导致连接异常
  • 真正治本是减少短连接——改用连接池、HTTP/2 复用、或让 client 主动 close() 后等待 server 发 FIN(避免主动断连方进入 TIME_WAIT)

这些参数之间存在隐式依赖,比如调大 tcp_rmem 后若没同步调高 rmem_max,应用仍无法突破单连接 256K 接收窗口;又比如 somaxconn 改了但应用未重启,listen backlog 实际还是旧值。调参不是改完 sysctl 就结束,得逐层验证到 socket 级状态。

text=ZqhQzanResources