Linux网络栈性能调优_内核参数说明【教程】

21次阅读

.net.core.somaxconn过低导致accept队列溢出,表现为ss -lnt中Recv-Q长期非零或Connection refused;需设为65535并同步调整应用backlog参数。

Linux网络栈性能调优_内核参数说明【教程】

.net.core.somaxconn 设置过低导致 accept 队列溢出

ss -lnt 显示 Recv-Q 长期非零,或应用日志频繁出现 Connection refused(尤其在突发流量下),大概率是 net.core.somaxconn 不足。该参数限制内核 listen socket 的全连接队列最大长度,不是应用层 backlog 参数能绕过的。

  • 默认值通常为 128,远低于现代 Web 服务需求;建议设为 65535 或更高
  • 需同时调整应用的 listen() 第二个参数(如 nginxlisten ... backlog=65535),否则仍受其限制
  • 修改后无需重启内核,但监听新端口的服务需重启才能生效(已有 listen socket 不会动态扩容)
  • 验证方式:
    sysctl net.core.somaxconn

    ss -lnt | grep :80

    观察 Recv-Q 是否持续

net.ipv4.tcp_tw_reuse 与 tcp_tw_recycle 的取舍

tcp_tw_reuse 在 TIME_WaiT 状态 socket 复用上安全有效;而 tcp_tw_recycle 已在 linux 4.12+ 彻底移除,且在 NAT 环境下必然引发连接失败——它依赖时间戳单调递增,但多客户端共用公网 IP 时,内核无法区分不同设备的时间戳偏移。

  • 只启用 net.ipv4.tcp_tw_reuse = 1,禁用 tcp_tw_recycle(设为 0 或直接不配置)
  • 搭配 net.ipv4.tcp_fin_timeout = 30 可进一步缩短 TIME_WAIT 持续时间(默认 60 秒)
  • 若仍有大量 TIME_WAIT,优先检查是否短连接滥用(如 http 未复用连接),而非盲目调参

接收缓冲区自动调优失效的典型表现

net.ipv4.tcp_rmem 三元组中第二项(默认接收窗口)设得过大(如 4096 65536 16777216),反而可能让内核放弃自动缩放:因为最小值和最大值跨度过大,TCP 倾向于长期维持高缓冲,浪费内存且增加延迟。

  • 推荐设置为 4096 131072 6291456(小、中、大三档合理拉开,但最大值不超 6MB)
  • 确认自动调优开启:net.ipv4.tcp_window_scaling = 1(必须为 1)
  • ss -i

    查看单连接实际 rwnd 值,若长期卡在最小值,说明应用读取太慢或缓冲区被锁死

  • 不要单独调大 rmem_max,它只影响 setsockopt(SO_RCVBUF) 上限,不改变 TCP 动态行为

net.core.netdev_max_backlog 过载引发丢包

该参数控制网卡中断后,软中断处理前,网络接收队列能暂存的数据包数量。当 ifconfig/proc/net/devrx_dropped 持续增长,且无硬件错误,就是此队列溢出的明确信号。

  • 默认值常为 1000,千兆以上网卡或高并发场景建议设为 5000–10000
  • 需配合调大 net.core.dev_weight(默认 64),提升软中断一次处理的包数,避免 backlog 积压
  • 注意:增大该值会增加内存占用(每个 sk_buff 约 2KB),不要无脑翻十倍
  • 验证方法:
    watch -n1 'cat /proc/net/snmp | grep -i "InErrs|InNoRoutes"

    ,若 InNoRoutes 异常升高,也可能是 backlog 溢出后包被静默丢弃

实际调优永远从监控出发:先看 ss -snetstat -scat /proc/net/snmp 找出具体瓶颈类型,再针对性改参。内核网络栈各层耦合紧密,一个参数改错可能把问题转移到更难诊断的位置。

text=ZqhQzanResources