เหตุผลที่คุณไม่สามารถเปลี่ยน RTO โดยเฉพาะได้ก็เพราะมันไม่ใช่ค่าคงที่ แทน (ยกเว้นสำหรับการเริ่มต้น SYN ตามธรรมชาติ) มันขึ้นอยู่กับ RTT (เวลาไปกลับ) สำหรับการเชื่อมต่อแต่ละครั้ง ที่จริงแล้วมันขึ้นอยู่กับรุ่น RTT ที่ราบรื่นและความแปรปรวน RTT ที่มีค่าคงที่บางตัวที่ถูกโยนลงไปในส่วนผสม ดังนั้นจึงเป็นค่าที่คำนวณได้แบบไดนามิกสำหรับการเชื่อมต่อ TCP แต่ละครั้งและฉันขอแนะนำบทความนี้ซึ่งมีรายละเอียดเพิ่มเติมเกี่ยวกับการคำนวณและ RTO โดยทั่วไป
มีความเกี่ยวข้องด้วยเช่นกันคือRFC 6298ซึ่งระบุ (ท่ามกลางสิ่งอื่น ๆ อีกมากมาย):
เมื่อใดก็ตามที่คำนวณ RTO หากน้อยกว่า 1 วินาที RTO SHOULD จะถูกปัดเศษเป็น 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
ด้านบนคือผลลัพธ์จาก VM ที่ฉันเข้าสู่ระบบด้วย SSH และมีการเชื่อมต่อสองสามเปิดที่ google.com อย่างที่คุณเห็น RTO นั้นถูกตั้งค่าเป็น 200-ish (มิลลิวินาที) คุณจะทราบว่าจะไม่ถูกปัดเศษเป็นค่า 1 วินาทีจาก RFC และคุณอาจคิดว่ามันค่อนข้างสูง นั่นเป็นเพราะมีขั้นต่ำในการเล่น (200 มิลลิวินาที) และสูงสุด (120 วินาที) เมื่อพูดถึง RTO สำหรับ Linux (มีคำอธิบายที่ดีในบทความที่ฉันลิงก์ด้านบน)
ดังนั้นคุณไม่สามารถแก้ไขค่า RTO ได้โดยตรง แต่สำหรับเครือข่ายที่สูญเสีย (เช่นไร้สาย) คุณสามารถลองปรับแต่งF-RTO ได้ (อาจเปิดใช้งานแล้วขึ้นอยู่กับ distro ของคุณ) จริงๆแล้วมีสองตัวเลือกที่เกี่ยวข้องกับ 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 (หลังการเปลี่ยนแปลง) คือ 15ms ในขณะที่การเชื่อมต่อ SSH (ก่อนการเปลี่ยนแปลง) คือ 200+ เหมือนก่อน
ฉันชอบวิธีนี้จริง ๆ - ช่วยให้คุณกำหนดค่าที่ต่ำกว่าในเส้นทางที่เหมาะสมมากกว่าในระดับโลก ในทำนองเดียวกัน (ดูที่หน้า man ip ) คุณสามารถปรับแต่ง rtt เริ่มต้นและ rttvar เริ่มต้นสำหรับเส้นทาง (ใช้เมื่อคำนวณ RTO แบบไดนามิก) แม้ว่ามันจะไม่ใช่วิธีแก้ปัญหาที่สมบูรณ์ในแง่ของการปรับแต่ง แต่ฉันคิดว่าสิ่งสำคัญส่วนใหญ่จะอยู่ที่นั่น คุณไม่สามารถปรับแต่งการตั้งค่าสูงสุด แต่ฉันคิดว่ามันจะไม่เป็นประโยชน์โดยทั่วไปในทุกกรณี