Linux

在 Linux 中更改 TCP RTO 值

  • August 15, 2017

我想更改連接的 TCP RTO (重新傳輸超時)值,我所做的一些閱讀表明我可以這樣做,但沒有透露在哪里以及如何更改它。

我查看了/proc/sys/net/ipv4變數,但沒有一個變數與 RTO 相關。如果有人能告訴我如何更改此值,我將不勝感激。

您不能專門更改 RTO 的原因是它不是靜態值。相反(當然,除了初始 SYN 之外)它基於每個連接的 RTT(往返時間)。實際上,它基於 RTT 的平滑版本和 RTT 變異數,其中包含一些常數。因此,它是每個 TCP 連接的動態計算值,我強烈推薦這篇文章,它更詳細地介紹了計算和 RTO。

同樣相關的是RFC 6298,它指出(在許多其他事情中):

每當計算 RTO 時,如果它小於 1 秒,則 RTO 應該向上舍入到 1 秒。

那麼核心是否總是將 RTO 設置為 1 秒?ss -i好吧,在 Linux 中,您可以通過執行以下命令來顯示打開連接的目前 RTO 值:

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 的 VM 的輸出。如您所見,RTO 實際上設置為 200-ish(毫秒)。您會注意到 RFC 沒有四捨五入到 1 秒的值,您可能還認為它有點高。這是因為對於 Linux 的 RTO,存在最小(200 毫秒)和最大(120 秒)界限(我在上面連結的文章中對此進行了很好的解釋)。

因此,您不能直接更改 RTO 值,但對於有損網路(如無線),您可以嘗試調整F-RTO(這可能已經啟用,具體取決於您的發行版)。實際上,您可以調整兩個與 F-RTO 相關的相關選項(這裡有很好的總結):

net.ipv4.tcp_frto
net.ipv4.tcp_frto_response

根據您嘗試優化的內容,這些可能有用也可能沒有用。

編輯:跟進從評論中調整 TCP 的 rto_min/max 值的能力。

您無法更改 TCP 的全域最小 RTO(順便說一句,您可以為 SCTP 更改 - 這些在 sysctl 中公開),但好消息是您可以調整每個路由上 RTO 的最小值基礎。這是我在 CentOS VM 上的路由表:

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 連接(更改前)與之前一樣為 200+。

我實際上喜歡這種方法 - 它允許您在適當的路線上設置較低的值,而不是在可能會破壞其他流量的全域範圍內。同樣(參見ip 手冊頁),您可以調整路由的初始 rtt 估計和初始 rttvar(在計算動態 RTO 時使用)。雖然在調整方面它不是一個完整的解決方案,但我認為大部分重要的部分都在那裡。您無法調整最大設置,但我認為在任何情況下通常都不會那麼有用。

引用自:https://unix.stackexchange.com/questions/210367