Lý do bạn không thể thay đổi RTO cụ thể là vì đó không phải là giá trị tĩnh. Thay vào đó (ngoại trừ SYN ban đầu, một cách tự nhiên), nó dựa trên RTT (Thời gian khứ hồi) cho mỗi kết nối. Trên thực tế, nó dựa trên một phiên bản RTT được làm mịn và phương sai RTT với một số hằng số được đưa vào hỗn hợp. Do đó, đây là một giá trị động, được tính toán cho mỗi kết nối TCP và tôi rất khuyến nghị bài viết này sẽ đi sâu vào chi tiết hơn về tính toán và RTO nói chung.
Cũng có liên quan là RFC 6298 , trong đó nêu rõ (trong số rất nhiều thứ khác):
Bất cứ khi nào RTO được tính toán, nếu nó nhỏ hơn 1 giây, thì RTO NÊN được làm tròn lên đến 1 giây.
Có phải kernel luôn đặt RTO thành 1 giây không? Chà, với Linux, bạn có thể hiển thị các giá trị RTO hiện tại cho các kết nối mở của mình bằng cách chạy ss -i
lệnh:
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
Trên đây là đầu ra từ một VM mà tôi đã đăng nhập bằng SSH và có một vài kết nối mở tới google.com. Như bạn có thể thấy, RTO trên thực tế được đặt thành 200-ish (mili giây). Bạn sẽ lưu ý rằng không được làm tròn đến giá trị 1 giây từ RFC và bạn cũng có thể nghĩ rằng nó hơi cao. Đó là bởi vì có giới hạn tối thiểu (200 mili giây) và tối đa (120 giây) khi nói về RTO cho Linux (có một lời giải thích tuyệt vời về điều này trong bài viết tôi đã liên kết ở trên).
Vì vậy, bạn không thể thay đổi trực tiếp giá trị RTO, nhưng đối với các mạng bị mất (như không dây), bạn có thể thử điều chỉnh F-RTO (điều này có thể đã được bật tùy thuộc vào bản phân phối của bạn). Thực tế, có hai tùy chọn liên quan đến F-RTO mà bạn có thể điều chỉnh (tóm tắt tốt ở đây ):
net.ipv4.tcp_frto
net.ipv4.tcp_frto_response
Tùy thuộc vào những gì bạn đang cố gắng tối ưu hóa, những thứ này có thể có hoặc không hữu ích.
EDIT: theo dõi khả năng điều chỉnh các giá trị rto_min / max cho TCP từ các bình luận.
Bạn không thể thay đổi RTO tối thiểu toàn cầu cho TCP (như một bên, bạn có thể làm điều đó cho SCTP - những thứ được hiển thị trong sysctl), nhưng tin tốt là bạn có thể điều chỉnh giá trị tối thiểu của RTO trên mỗi tuyến nền tảng. Đây là bảng định tuyến của tôi trên máy ảo CentOS của tôi:
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
Tôi có thể thay đổi giá trị rto_min trên tuyến mặc định như sau:
ip route change default via 10.0.2.2 dev eth0 rto_min 5ms
Và bây giờ, bảng định tuyến của tôi trông như thế này:
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
Cuối cùng, hãy bắt đầu một kết nối và kiểm tra ss -i
xem điều này có được tôn trọng không:
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
Sự thành công! Rto trên kết nối HTTP (sau khi thay đổi) là 15ms, trong khi kết nối SSH (trước khi thay đổi) là hơn 200 như trước.
Tôi thực sự thích cách tiếp cận này - nó cho phép bạn đặt giá trị thấp hơn trên các tuyến thích hợp hơn là trên toàn cầu nơi nó có thể làm hỏng lưu lượng khác. Tương tự (xem trang ip man ), bạn có thể điều chỉnh ước tính rtt ban đầu và rttvar ban đầu cho tuyến đường (được sử dụng khi tính toán RTO động). Mặc dù nó không phải là một giải pháp hoàn chỉnh về mặt tinh chỉnh, tôi nghĩ rằng hầu hết các phần quan trọng đều ở đó. Bạn không thể điều chỉnh cài đặt tối đa, nhưng tôi nghĩ rằng điều đó sẽ không hữu ích trong mọi trường hợp.