在 Linux 中更改 TCP RTO 值

在 Linux 中更改 TCP RTO 值

我想更改 TCP RTO(重传超时)连接的价值,我所做的一些阅读表明我可以做到这一点,但没有透露在哪里以及如何改变它。

我查看了这些/proc/sys/net/ipv4变量,但没有一个变量与 RTO 相关。如果有人能告诉我如何改变这个值,我将不胜感激。

答案1

您无法专门更改 RTO 的原因是它不是静态值。相反(自然地,初始 SYN 除外)它基于每个连接的 RTT(往返时间)。实际上,它基于 RTT 的平滑版本和 RTT 方差以及一些常量的混合。因此,它是每个 TCP 连接的动态计算值,我强烈推荐本文其中更详细地介绍了计算和一般 RTO。

同样相关的是RFC 6298其中指出(以及许多其他内容):

每当计算 RTO 时,如果它小于 1 秒,则 RTO 应向上舍入为 1 秒。

那么内核总是将 RTO 设置为 1 秒吗?那么,在 Linux 中,您可以通过运行以下命令来显示打开的连接的当前 RTO 值ss -i

State       Recv-Q Send-Q                                                  Local Address:Port     Peer Address:Port
ESTAB       0      0                                                           10.0.2.15:52861   216.58.219.46:http
     cubic rto:204 rtt:4/2 cwnd:10 send 29.2Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:ssh          10.0.2.2:52586
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                           10.0.2.15:52864   216.58.219.46:http
     cubic rto:204 rtt:4.5/4.5 cwnd:10 send 26.0Mbps rcv_space:14600

上面是我使用 SSH 登录的虚拟机的输出,并且有几个与 google.com 打开的连接。正如您所看到的,RTO 实际上设置为 200 左右(毫秒)。您会注意到,该值并未四舍五入为 RFC 中的 1 秒值,您可能还认为它有点高。这是因为 Linux 的 RTO 存在最小(200 毫秒)和最大(120 秒)界限(我上面链接的文章对此有很好的解释)。

因此,您不能直接更改 RTO 值,但对于有损网络(例如无线),您可以尝试调整快速RTO(这可能已经启用,具体取决于您的发行版)。实际上有两个与 F-RTO 相关的选项可以调整(很好的总结这里):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

根据您尝试优化的内容,这些可能有用也可能没用。

编辑:根据评论跟踪调整 TCP 的 rto_min/max 值的能力。

您无法更改 TCP 的全局最小 RTO(顺便说一句,您可以为 SCTP 执行此操作 - 这些在 sysctl 中公开),但好消息是您可以调整每个路由上 RTO 的最小值基础。这是我的 CentOS 虚拟机上的路由表:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0

我可以更改默认路由上的 rto_min 值,如下所示:

ip route change default via 10.0.2.2 dev eth0 rto_min 5ms

现在,我的路由表如下所示:

ip route
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15 
169.254.0.0/16 dev eth0  scope link  metric 1002 
default via 10.0.2.2 dev eth0  rto_min lock 5ms

最后,让我们启动一个连接并检查ss -i是否已遵守这一点:

ss -i
State       Recv-Q Send-Q                                               Local Address:Port                                                   Peer Address:Port   
ESTAB       0      0                                                        10.0.2.15:ssh                                                        10.0.2.2:50714   
     cubic rto:201 rtt:1.5/0.75 ato:40 cwnd:10 send 77.9Mbps rcv_space:14600
ESTAB       0      0                                                        10.0.2.15:39042                                                 216.58.216.14:http    
     cubic rto:15 rtt:5/2.5 cwnd:10 send 23.4Mbps rcv_space:14600

成功了!HTTP 连接(更改后)的 rto 为 15ms,而 SSH 连接(更改前)的 rto 与之前一样为 200+。

我实际上喜欢这种方法 - 它允许您在适当的路线上设置较低的值,而不是在全局上设置较低的值,否则可能会搞砸其他流量。同样(参见IP 手册页)您可以调整路线的初始 rtt 估计和初始 rttvar(在计算动态 RTO 时使用)。虽然在调整方面它不是一个完整的解决方案,但我认为大多数重要的部分都在那里。您无法调整最大设置,但我认为在任何情况下这通常都不会那么有用。

相关内容