概述
本文介绍影响 TCP 传输速率的关键因素,并提供常见问题的排查思路与解决方案,帮助您在云服务器上优化 TCP 传输性能。TCP 传输速率受多个层面因素影响,主要包括:
网络链路:带宽、RTT(往返时延)、丢包与乱序
窗口大小:接收窗口、发送窗口、拥塞窗口
缓冲区配置:TCP socket 的发送/接收缓冲区水位
拥塞控制算法:不同算法在不同网络环境下的表现差异
内核协议栈参数:时间戳、初始窗口、GSO 等特性
主机资源:CPU 调度延迟、软中断处理延迟
其中,窗口大小与缓冲区配置是最常见且可通过调优快速见效的环节。
带宽时延乘积(BDP)与窗口大小
BDP 公式
TCP 使用窗口机制防止快速发送方超越慢速接收方。随着网络带宽增加、链路变长,确认收到数据需要更长时间。这种带宽与延迟的关系称为带宽时延乘积(BDP),表示为填满网络管道应发送的最佳数据量:
BDP(位)= 带宽(位/秒)× RTT(秒)
计算示例
假设两台设备间带宽为 10 Gbps,RTT 为 50 ms,TCP 默认窗口大小为 65535 字节,能否充分利用带宽?
带宽 =(65535 字节 × 8 位/字节)/ 0.050 秒 ≈ 10.49 Mbit/s
可见默认窗口大小远无法达到 10 Gbps 的理论带宽。要将该链路打满,所需窗口大小为:
窗口大小 =(10000 Mbps × 0.050 秒)/ 8 位/字节 ≈ 62.5 MB
注意:
62.5 MB 为理论值,实际传输性能还受 CPU 调度、应用层开销、数据包大小、内核窗口水位等因素影响。
窗口扩展因子
为解决高延迟网络下窗口不足的问题,RFC 1323 定义了窗口扩展选项(Window Scale),在 TCP option 中添加一个扩展因子,将原本 16 位的窗口大小扩大若干倍。
内核控制参数:
net.ipv4.tcp_window_scaling = 1
默认开启,建议保持开启状态以支持高延迟网络的窗口扩展。
TCP 缓冲区参数调优
参数说明
参数 | 默认值 | 说明 |
net.ipv4.tcp_rmem | 4096 131072 6291456 | TCP socket 接收缓冲区水位(min / default / max,单位:字节) |
net.ipv4.tcp_wmem | 4096 16384 4194304 | TCP socket 发送缓冲区水位(min / default / max,单位:字节) |
三个值的含义:
min:为 TCP socket 预留的最小缓冲区内存,即使在内存紧张时也至少保留此数量
default:TCP socket 的默认缓冲区大小,一般低于
net.core.rmem_max / net.core.wmem_maxmax:TCP socket 缓冲区最大值,必须小于或等于
rmem_max / wmem_max调优建议
高延迟、高带宽网络(如跨地域传输):将
max 值调大至 BDP 的 2 倍以上查看当前配置:
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem动态调整示例(将发送/接收缓冲区上限调至 20 MB):
sysctl -w net.ipv4.tcp_rmem='4096 131072 20971520'sysctl -w net.ipv4.tcp_wmem='4096 16384 20971520'
永久生效请写入
/etc/sysctl.conf 后执行 sysctl -p诊断方法
用 ss 命令查看窗口瓶颈
ss 命令可查看 TCP 连接的详细状态,是定位窗口瓶颈的首选工具。当流量打不上去时,重点关注以下字段:字段 | 含义 |
rwnd_limited | 因对端接收窗口限制导致的暂停发包时间占比 |
sndbuf_limited | 因本端发送缓冲区不足导致的暂停发包时间占比 |
cwnd | 拥塞窗口大小 |
snd_wnd | 当前发送窗口 |
bytes_sent / bytes_acked | 已发送/已确认字节数 |
retrans | 重传次数 |
busy | 连接忙碌时长 |
pacing_rate / delivery_rate | 发送速率 / 投递速率 |
查看命令:
ss -ie 'dst <对端IP>'
判断逻辑:
若
rwnd_limited 占比较高,即对端接收窗口不足,需调大接收方 tcp_rmem若
sndbuf_limited 占比较高,即本端发送缓冲区不足,需调大发送方 tcp_wmem若两者都很低但
busy 时长很高且带宽上不去,通常为链路延迟或丢包导致,需检查网络质量或 qdisc 限速示例输出(简化)
ss -ie 'dst 10.0.0.16'tcp ESTAB 0 3932288 10.0.0.15:49550 10.0.0.16:5201ts sack cubic wscale:7,7 rto:251 rtt:50.53/0.051 mss:1412cwnd:4474 send 1Gbpsrwnd_limited:4981ms(63.5%) sndbuf_limited:101ms(1.3%)
上例中
rwnd_limited 占比 63.5%,说明接收窗口是主要瓶颈。用 iperf3 验证带宽
iperf3 -c <服务端IP> -i 1 -t 60
通过 iperf3 测试基线带宽,再结合
ss 观察窗口受限情况,可快速定位瓶颈。常见问题排查
高延迟网络下 TCP 性能低(窗口不足)
问题现象
跨地域或高延迟链路下,iperf3 测试带宽远低于物理带宽,如 10 Gbps 链路仅跑到约 480 Mbps。
可能原因
默认 TCP 窗口大小不足以填满高延迟管道(BDP 计算不足),窗口扩展因子未生效。
排查方法
1. 用
ss -ie 查看连接的 rwnd_limited 和 sndbuf_limited 占比。2. 若
rwnd_limited 占比高(如 63.5%),确认接收窗口为瓶颈。3. 确认
net.ipv4.tcp_window_scaling = 1 已开启。解决方案
调大发送方与接收方的 TCP 缓冲区上限,使其覆盖 BDP 所需窗口大小:
sysctl -w net.ipv4.tcp_rmem='4096 131072 20971520'sysctl -w net.ipv4.tcp_wmem='4096 16384 20971520'
调优后重新测试,带宽应显著提升。
TCP 传输速度受缓冲区限制
问题现象
ss 输出显示 sndbuf_limited 占比较高,流量上不去。可能原因
发送缓冲区上限(
tcp_wmem 的 max 值)设置过小,应用层数据积压在发送队列。排查方法
ss -ie 'dst <对端IP>' | grep sndbuf_limited
查看
sndbuf_limited 占比和 Send-Q 积压情况。解决方案
调大
net.ipv4.tcp_wmem 的 max 值,同时确保 net.core.wmem_max 不小于该值:sysctl -w net.core.wmem_max=20971520sysctl -w net.ipv4.tcp_wmem='4096 16384 20971520'
拥塞控制算法选择
问题现象
不同网络环境下传输性能差异明显,同一链路更换算法后吞吐变化较大。
可能原因
默认拥塞控制算法(如 cubic)在特定场景(长肥管道、高丢包)下表现不佳。
排查方法
查看当前拥塞控制算法:
sysctl net.ipv4.tcp_congestion_control
查看可用算法:
sysctl net.ipv4.tcp_available_congestion_control
解决方案
根据场景选择合适算法:
高延迟、高带宽长肥管道:考虑使用 BBR
一般场景:cubic 即可
sysctl -w net.ipv4.tcp_congestion_control=bbr
tc qdisc 限速
问题现象
带宽稳定卡在某一固定值,
ss 显示窗口未受限,rwnd_limited / sndbuf_limited 占比低,但 busy 时长居高不下。可能原因
网络接口配置了 tc qdisc 限速规则,或 netem 规则默认
limit 过小导致丢包。排查方法
查看 qdisc 配置与丢包统计:
tc -s qdisc show dev eth0
重点观察
dropped 计数和 backlog 积压。若 netem 规则 limit 默认为 1000,当积压超过该值会丢包。解决方案
若为业务限速,确认是否符合预期
若为 netem 延时模拟场景,调大 limit 参数:
tc qdisc del dev eth0 root netem 2>/dev/nulltc qdisc add dev eth0 root netem delay 25ms limit 10000
内核 GSO 功能影响
问题现象
相同硬件与配置下,不同内核版本 TCP 传输性能差异显著。在配置 tc netem 延时规则后,低版本内核出现 tc 丢包且带宽上不去。
可能原因
内核 GSO(Generic Segmentation Offload)功能未启用,协议栈无法将多个 TCP 报文聚合后统一交给驱动分片处理,导致 tc 队列积压与丢包。
排查方法
1. 对比不同内核版本下的 tc 丢包统计:
tc -s qdisc show dev eth0
2. 正常内核
dropped 为 0,backlog 较小;异常内核 dropped 增多,backlog 积压严重3. 检查 GSO 是否开启:
ethtool -k eth0 | grep gso
解决方案
升级至较新版本的 TencentOS Server 内核,高版本内核默认强制开启 GSO
或手动开启网卡 GSO 功能:
ethtool -K eth0 gso on
总结:关键调优参数速查表
参数 | 说明 | 调优建议 |
net.ipv4.tcp_rmem | TCP 接收缓冲区水位(min/default/max) | 高延迟网络将 max 调至 BDP 的 2 倍以上 |
net.ipv4.tcp_wmem | TCP 发送缓冲区水位(min/default/max) | 同上,确保发送缓冲区足够 |
net.core.rmem_max | 最大接收缓冲区上限 | 不小于 tcp_rmem 的 max 值 |
net.core.wmem_max | 最大发送缓冲区上限 | 不小于 tcp_wmem 的 max 值 |
net.ipv4.tcp_window_scaling | 窗口扩展因子 | 保持开启(=1) |
net.ipv4.tcp_congestion_control | 拥塞控制算法 | 高延迟链路可尝试 bbr |
net.ipv4.tcp_timestamps | TCP 时间戳 | 建议开启,有助于 RTT 测量与乱序检测 |
net.ipv4.tcp_slow_start_after_idle | 空闲后慢启动 | 长连接场景可关闭(=0) |
网卡 GSO | 通用分段卸载 | 保持开启 |