Powodem, dla którego nie możesz zmienić RTO, jest to, że nie jest to wartość statyczna. Zamiast tego (oczywiście z wyjątkiem początkowej SYN), jest ona oparta na RTT (Round Trip Time) dla każdego połączenia. W rzeczywistości opiera się na wygładzonej wersji RTT i wariancji RTT z pewnymi stałymi wrzuconymi do miksu. Dlatego jest to dynamiczna, obliczona wartość dla każdego połączenia TCP i bardzo polecam ten artykuł, który szczegółowo omawia obliczenia i RTO.
Istotna jest również RFC 6298, która stwierdza (między innymi):
Za każdym razem, gdy RTO jest obliczane, jeśli jest ono krótsze niż 1 sekunda, wówczas RTO POWINNY być zaokrąglane w górę do 1 sekundy.
Czy wtedy jądro zawsze ustawia RTO na 1 sekundę? Cóż, w systemie Linux możesz wyświetlić bieżące wartości RTO dla otwartych połączeń, uruchamiając ss -i
polecenie:
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
Powyżej jest wyjście z maszyny wirtualnej, do której jestem zalogowany za pomocą SSH i ma kilka połączeń otwartych na google.com. Jak widać RTO jest ustawiony na 200-ish (milisekund). Zauważysz, że nie jest on zaokrąglany do 1 sekundy wartości z RFC, i możesz również pomyśleć, że jest trochę wysoki. To dlatego, że istnieją granice min (200 milisekund) i maksimum (120 sekund), jeśli chodzi o RTO dla Linuksa (jest to świetne wyjaśnienie w artykule, który podłączyłem powyżej).
Nie możesz więc bezpośrednio zmieniać wartości RTO, ale w przypadku sieci o dużej mocy (takich jak sieć bezprzewodowa) możesz spróbować ulepszyć F-RTO (może to być już włączone w zależności od dystrybucji). W rzeczywistości istnieją dwie powiązane opcje związane z F-RTO, które można dostosować (dobre podsumowanie tutaj ):
net.ipv4.tcp_frto
net.ipv4.tcp_frto_response
W zależności od tego, co próbujesz zoptymalizować, mogą one być przydatne lub nie.
EDYCJA: w następstwie możliwości dostosowania wartości rto_min / max dla TCP z komentarzy.
Nie możesz zmienić globalnego minimalnego RTO dla TCP (na marginesie, możesz to zrobić dla SCTP - są one widoczne w sysctl), ale dobrą wiadomością jest to, że możesz dostosować minimalną wartość RTO na trasie podstawa. Oto moja tabela routingu na mojej maszynie Wirtualnej 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
Mogę zmienić wartość rto_min na domyślnej trasie w następujący sposób:
ip route change default via 10.0.2.2 dev eth0 rto_min 5ms
A teraz moja tabela routingu wygląda następująco:
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
Na koniec zainicjuj połączenie i sprawdź, ss -i
czy zostało to przestrzegane:
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
Sukces! Rto na połączeniu HTTP (po zmianie) wynosi 15ms, podczas gdy połączenie SSH (przed zmianą) wynosi 200+ jak poprzednio.
Naprawdę podoba mi się to podejście - pozwala ustawić niższą wartość na odpowiednich trasach, a nie globalnie, gdzie może to zepsuć inny ruch. Podobnie (patrz strona podręcznika użytkownika ip ) możesz dostosować początkową wartość szacunkową rtt i początkową wartość rttvar dla trasy (używaną przy obliczaniu dynamicznego RTO). Chociaż nie jest to kompletne rozwiązanie w zakresie poprawiania, myślę, że większość ważnych elementów jest tam. Nie możesz zmienić maksymalnego ustawienia, ale myślę, że w ogóle nie będzie to tak przydatne.