直接调大tcp_rmem第三个值不能单独生效,必须同时满足:net.core.rmem_max不小于该值、tcp_window_scaling=1开启、BDP×2合理设定上限,并排除应用层SO_RCVBUF覆盖。

直接改 net.ipv4.tcp_rmem 的第三个值(最大值),就能控制内核自动调整接收窗口的上限。但光调这个不够,它得和几个关键参数配合才能真正生效。
确认当前设置和限制
先看真实配置,别凭经验猜:
- 运行
sysctl net.ipv4.tcp_rmem,输出如4096 87380 6291456,第三个数就是当前自动扩缩容的上限(这里是 6MB) - 再查
sysctl net.core.rmem_max,如果这个值比 tcp_rmem 的最大值还小,那上限实际会被截断——tcp_rmem 的第三个值必须 ≤ rmem_max,否则无效 - 用
ss -i查某个活跃连接,看rcv_wnd是否接近你设的上限;如果长期卡在默认值(比如 128KB),说明自动扩缩没起来,大概率是被拦住了
算出合理的上限值
上限不是越大越好,核心依据是带宽延迟积(BDP):
- BDP = 带宽(字节/秒) × RTT(秒)。例如 100Mbps 链路 + 100ms RTT → BDP ≈ 1.25MB
- 推荐上限 ≥ BDP × 2,留出余量应对突发流量和时延抖动
- 盲目设到 16MB 可能浪费内存、拖慢小包响应,尤其在高并发短连接场景下
配套开启自动调优机制
tcp_rmem 最大值只是“天花板”,下面这些才是让窗口真能长上去的开关:
-
net.ipv4.tcp_window_scaling = 1:必须开,否则窗口卡死在 64KB -
net.ipv4.tcp_timestamps = 1:辅助内核准确测 RTT,影响窗口增长节奏 -
net.ipv4.tcp_moderate_rcvbuf = 1:启用内核自动调节逻辑(默认一般已开) - 避免应用层调
setsockopt(..., SO_RCVBUF, ...)锁死缓冲区大小,会绕过自动调优
临时修改与永久生效
改完要验证是否落地:
- 临时改:执行
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"(示例设上限为 16MB) - 同时补上:
sysctl -w net.core.rmem_max=16777216,确保不被截断 - 永久生效:把两行写进
/etc/sysctl.conf,再运行sysctl -p - 改完立刻用
ss -i或重连测试,观察 rcv_wnd 是否随流量上升











