Причина, по которой вы не можете изменить RTO, заключается в том, что это не статическое значение. Вместо этого (за исключением первоначального SYN, естественно), он основан на RTT (Round Trip Time) для каждого соединения. На самом деле, он основан на сглаженной версии 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 мкс (миллисекунд). Вы заметите, что значение не округлено до 1 секунды из RFC, и вы также можете подумать, что оно немного выше. Это связано с тем, что для RTO для Linux существуют минимальные (200 миллисекунды) и максимальные (120 секунд) границы (это прекрасно объясняется в статье, на которую я ссылался выше).
Таким образом, вы не можете изменить значение RTO напрямую, но для сетей с потерями (например, беспроводных) вы можете попробовать настроить F-RTO (это может быть уже включено в зависимости от вашего дистрибутива). На самом деле есть два связанных параметра, связанных с F-RTO, которые вы можете настроить (хорошее резюме здесь ):
net.ipv4.tcp_frto
net.ipv4.tcp_frto_response
В зависимости от того, для чего вы пытаетесь оптимизировать, они могут или не могут быть полезны.
РЕДАКТИРОВАТЬ: следуя за возможностью настроить значения rto_min / max для TCP из комментариев.
Вы не можете изменить глобальный минимальный RTO для TCP (кроме того, вы можете сделать это для 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
Успех! Значение rto для HTTP-соединения (после изменения) составляет 15 мс, тогда как SSH-соединение (до изменения) составляет 200+, как и раньше.
Мне действительно нравится этот подход - он позволяет вам установить более низкое значение на соответствующих маршрутах, а не глобально, где это может испортить другой трафик. Аналогично (см. Справочную страницу ip ) вы можете настроить начальную оценку rtt и начальную rttvar для маршрута (используется при расчете динамического RTO). Хотя это не полное решение с точки зрения настройки, я думаю, что большинство важных частей есть. Вы не можете настроить максимальную настройку, но я думаю, что в общем случае она не будет столь полезной.