한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Sách trắng lag game › L8 Socket và giao thức

TCP RTO và exponential backoff RTO and exponential backoff

ID nguyên nhân sk-rto · Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)

Mở thẻ gốc có hình minh họa và thí nghiệm →

Mỗi lần truyền lại tiếp tục thất bại, thời gian chờ lại tăng gấp đôi, nên đường truyền chỉ đứt chốc lát cũng thành một lần đứng dài.

Vì sao Đường truyền bị đứt trong chốc lát, các lần truyền lại cũng liên tiếp thất bại → Dẫn đến Thời gian chờ đến lần thử sau tăng gấp đôi mỗi lần, như 0,3 → 0,6 → 1,2 → 2,4 giây (với ping 100 ms) → Trên màn hình Đường truyền chỉ đứt 1 giây nhưng game đứng hình hơn 2 giây. Đứt lâu hơn thì cuối cùng mất kết nối

Triệu chứng
Đứng hình, Mất kết nối
Yếu tố
Mất gói, Ngưng trệ
Ai gặp phải
Chỉ mình tôi
Khi nào
Thỉnh thoảng bất chợt, Khi di chuyển hoặc chuyển bản đồ
Phụ trách
Phụ trách chính Phát triển server (Đội phát triển game) · Phối hợp Phát triển client (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Server: phản hồi heartbeat, nếu không nhận được trong một khoảng thời gian thì chủ động đóng kết nối (dùng TCP_USER_TIMEOUT để bỏ cuộc sớm hơn), nối lại phiên bằng session token, dùng UDP tin cậy. Client: gửi heartbeat với khoảng cách ngắn, khi mất phản hồi thì kết nối lại ngay, không chờ TCP truyền lại.
Con số tham khảo
RTO (thời gian chờ truyền lại) của Linux tối thiểu là “ping + 200 ms”, và bắt đầu từ 1 giây khi đang thiết lập kết nối. Với cấu hình mặc định (tcp_retries2=15), dù truyền lại liên tục thất bại, phải sau khoảng 15 phút kết nối mới bị bỏ.
Trên đồ thị
Đứt quãng rồi dồn về · RTO và backoff theo từng kết nối, số lần RTO hết hạn
Chỗ cần xem
rto (thời gian chờ truyền lại, ms) và backoff (số lần hết hạn liên tiếp) của kết nối đang đứng, xem bằng ss -ti; với cả server, xem mức tăng TcpExtTCPTimeouts (số lần timer truyền lại hết hạn) trong nstat -az
Đúng nếu
kết nối đang đứng có backoff từ 1 trở lên và rto đã tăng lên hàng giây, đồng thời TCPTimeouts tăng vào lúc đó
Loại trừ nếu
truyền lại kết thúc bằng truyền lại nhanh và không có RTO hết hạn (khi đó lần đứng ngắn) → “TCP HOL blocking”
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)

Nguồn

  1. RFC 6298: Computing TCP's Retransmission Timer IETF
    RTO ban đầu 1 giây, nhân đôi mỗi lần timer hết hạn (exponential backoff)
  2. net/ipv4/tcp_input.c (Linux v6.12) Linux kernel
    RTO của Linux = RTT làm mượt + độ biến thiên RTT, và độ biến thiên có mức sàn là tcp_rto_min (200 ms), nên RTO luôn từ RTT + 200 ms trở lên
  3. IP Sysctl Linux kernel
    tcp_rto_min_us mặc định 200 ms, RTO đầu tiên của yêu cầu kết nối là 1 giây, với tcp_retries2=15 thì phải ít nhất 924,6 giây (khoảng 15 phút) mới bỏ cuộc
  4. ss(8) — Linux manual page iproute2
    rto (timer truyền lại, ms) và backoff (số lần exponential backoff) trong -i
  5. net/ipv4/proc.c (Linux v6.12) Linux kernel
    Tên bộ đếm mà nstat hiển thị: TCPTimeouts trong nhóm TcpExt
  6. net/ipv4/tcp_timer.c (Linux v6.12) Linux kernel
    Mỗi lần timer truyền lại hết hạn, TCPTimeouts tăng, backoff tăng thêm một và RTO nhân đôi (đến mức tối đa)

Nguyên nhân nên xem cùng

Cùng tầng: L8 Socket và giao thức

Nguyên nhân ở tầng khác gây cùng triệu chứng (Đứng hình)

Xem thẻ gốc có hình minh họa và thí nghiệm