Truyền lại không cần thiết do độ trễ tăng vọt Spurious RTO from delay spikes
ID nguyên nhân rt-spurious-delay · Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)
Gói tin vẫn đến nơi, chỉ là đến rất muộn trong chốc lát; nếu độ trễ đó dài hơn RTO thì bên gửi xác định là mất rồi truyền lại.
Vì sao Bufferbloat, chế độ tiết kiệm điện của Wi-Fi, mạng di động chuyển trạng thái vô tuyến, máy ảo bị tạm dừng làm độ trễ tức thời lên vài trăm ms → Dẫn đến RTO hết hạn trước nên truyền lại, gói gốc cũng đến ngay sau đó (bên nhận nhận trùng) → Trên màn hình Đứng hình và tua nhanh là do chính độ trễ tăng vọt. Truyền lại không cần thiết hầu như không làm đứng hình lâu hơn, chỉ đẩy chỉ số truyền lại lên nên bị hiểu nhầm là mất gói
Phụ trách chính Bên ngoài (Bên ngoài) · Phối hợp Hạ tầng server (Đội hạ tầng), Phát triển client (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Với client Android 10 trở lên, xin chế độ Wi-Fi độ trễ thấp khi đang chơi (Wi-Fi lock WIFI_MODE_FULL_LOW_LATENCY, chỉ có hiệu lực khi màn hình bật và game đang chạy ở foreground) để giảm độ trễ tăng vọt do tiết kiệm điện.
Việc cần làm (Đội hạ tầng)
Tránh loại instance burstable, không hạ RTO tối thiểu quá thấp, giữ F-RTO và timestamp (tcp_frto, tcp_timestamps), xem chỉ số truyền lại cùng với TCPSpuriousRTOs và TCPDSACKRecv trong nstat để không hiểu nhầm là mất gói.
Việc cần làm (Bên ngoài)
Để giảm chính độ trễ tăng vọt, hướng dẫn người chơi bật SQM trên router, tắt tiết kiệm điện Wi-Fi.
Con số tham khảo
Linux dùng F-RTO để phát hiện RTO không cần thiết và có thể khôi phục lại lượng gửi đã bị giảm. Kiểm tra bằng TCPSpuriousRTOs (số lần xác định là RTO không cần thiết) và TCPDSACKRecv (số lần bên nhận báo “đã nhận rồi”) trong nstat.
Trên đồ thị
Thỉnh thoảng vọt lên bất chợt · RTT (ping), số RTO không cần thiết
Chỗ cần xem
Chạy nstat cách nhau 1 phút, xem cùng lúc phần tăng của TcpExtTCPTimeouts (RTO hết hạn), TcpExtTCPSpuriousRTOs, TcpExtTCPDSACKRecv, TcpExtTCPLostRetransmit. Nếu có bản bắt gói thì dùng filter Wireshark tcp.analysis.spurious_retransmission
Đúng nếu
khi RTO tăng thì TcpExtTCPSpuriousRTOs hoặc TcpExtTCPDSACKRecv cũng tăng theo, cùng lúc RTT vọt lên vài trăm ms. Bản bắt gói phía nhận có cả gói gốc lẫn gói truyền lại
Loại trừ nếu
TcpExtTCPSpuriousRTOs và DSACK không đổi nhưng TcpExtTCPLostRetransmit (mất cả gói đã gửi lại) tăng → mất gói thật. RTT không vọt lên mà chỉ DSACK luôn nhiều → “Truyền lại nhanh không cần thiết do gói đến sai thứ tự”
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
SNMP counterLinux kernel TcpExtTCPSpuriousRTOs (RTO không cần thiết do F-RTO phát hiện), TcpExtTCPDSACKRecv (số DSACK đã nhận), TcpExtTCPLostRetransmit (số lần SACK báo gói đã gửi lại lại bị mất)
IP SysctlLinux kernel tcp_frto mặc định bật (có lợi cho mạng không dây có RTT dao động), tcp_timestamps mặc định 1
WifiManagerAndroid (Google) WIFI_MODE_FULL_LOW_LATENCY (API 29, Android 10): Wi-Fi lock độ trễ thấp, chỉ có hiệu lực khi đang kết nối với AP, màn hình bật và ứng dụng đang chạy ở foreground
net/ipv4/proc.cLinux kernel Tên counter trong nstat: TCPTimeouts, TCPSpuriousRTOs, TCPDSACKRecv, TCPLostRetransmit
net/ipv4/tcp_timer.cLinux kernel TCPTimeouts tăng mỗi khi timer truyền lại (RTO) hết hạn