应直接调高 net.ipv4.tcp_mem 三值(单位:页),而非增大 tcp_rmem/tcp_wmem;low 设为 sockstat 中 TCP: mem 峰值的 0.7–0.8 倍,pressure 为 low×1.2~1.3,high ≥ 峰值1.5倍且≤物理内存15%。

直接改 net.ipv4.tcp_mem 三值,别碰默认缓冲区大小
报错本质是 TCP 全局内存用量超了 high 阈值,触发内核丢包/拒连。此时最有效、最安全的干预就是调高 net.ipv4.tcp_mem 的三个页数(单位:页,1页=4KB),而不是盲目拉高 tcp_rmem 或 tcp_wmem——后者只会让单连接更吃内存,反而加速触达上限。
-
low:设为当前/proc/net/sockstat中TCP: mem峰值的 0.7–0.8 倍(换算成页);太低会过早进入压力模式,影响吞吐 -
pressure:建议设为low × 1.2~1.3,留出平滑收缩空间;不要和low太接近,否则缓冲区频繁抖动 -
high:必须 ≥ 当前峰值的 1.5 倍(页),且不超过总物理内存的 15%(例如 64GB 内存 → ≤ 9.6GB ≈ 2,400,000 页);设太高可能挤占 page cache,影响磁盘 IO
典型场景推荐值(按内存容量粗略划分)
以下数值单位均为「页」,已换算为 4KB 每页,适用于常规高并发服务(如 Web API、消息代理),非容器化裸机环境:
- 16GB 内存:
net.ipv4.tcp_mem = 131072 174762 262144(≈ 512MB / 682MB / 1024MB) - 32GB 内存:
net.ipv4.tcp_mem = 262144 349525 524288(≈ 1GB / 1.36GB / 2GB) - 64GB 内存:
net.ipv4.tcp_mem = 524288 699050 1048576(≈ 2GB / 2.72GB / 4GB)
注意:银河麒麟等国产系统出厂值常低至 25401 33869 50802(≈ 100MB / 133MB / 200MB),远不够万级连接,必须调。
配套必须调的两个硬上限
tcp_mem 是全局页数限制,但单 socket 缓冲区若被应用层用 setsockopt(SO_RCVBUF) 拉得过大,仍可能绕过压力控制。因此要同步收紧上限:
- 确保
net.core.rmem_max≥net.ipv4.tcp_rmem[2](即 TCP 读缓存最大值),否则tcp_rmem[2]实际无效 - 同理,
net.core.wmem_max≥net.ipv4.tcp_wmem[2] - 推荐组合(单位字节):
net.core.rmem_max = 134217728(128MB),net.core.wmem_max = 134217728
这两个值不建议超过 256MB,否则可能引发 skb 分配失败或 soft lockup。
验证是否生效 + 容易踩的坑
改完 /etc/sysctl.conf 后必须执行 sysctl -p,然后看实时效果:
- 查当前用量:
awk '/TCP:/ {print $3}' /proc/net/sockstat(输出为页数) - 查生效值:
sysctl net.ipv4.tcp_mem,确认不是旧值(某些 systemd 系统需加--system) - 常见坑:写错单位(把字节当页)、三个值没空格分隔、
tcp_mem和tcp_rmem数值倒挂(比如high )导致内核静默忽略整行 - 更隐蔽的坑:某些云主机(如阿里云部分 ECS)内核编译时禁用了
CONFIG_TCP_CONG_BBR或限制了tcp_mem上限,sysctl -w会成功但实际不生效,需检查dmesg | grep tcp
真正关键的从来不是“调多大”,而是确认 /proc/net/sockstat 的 TCP: mem 峰值稳定落在 low 和 pressure 之间——这才是压力可控的标志。










