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

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

Keepalive mặc định 2 giờ TCP keepalive defaults

ID nguyên nhân sk-keepalive · 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), Hạ tầng server (Đội hạ tầng)

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

Khi bên kia biến mất mà không gửi tín hiệu đóng kết nối, rất lâu sau TCP mới phát hiện. Keepalive (tính năng của TCP kiểm tra xem kết nối nhàn rỗi còn sống không) mặc định tắt, và dù có bật thì kết nối cũng phải nhàn rỗi 2 giờ mới bắt đầu kiểm tra.

Vì sao Client biến mất mà không có tín hiệu đóng kết nối, do mất điện hoặc rớt đường truyền → Dẫn đến Server coi kết nối vẫn còn sống (keepalive mặc định 7.200 giây; nếu đang gửi dở dữ liệu thì mất khoảng 15 phút mới bỏ truyền lại) → Trên màn hình Nhân vật ma còn nằm lại, vào lại game thì bị lỗi “Tài khoản đang đăng nhập”

Triệu chứng
Không vào được·kẹt loading, Không hiển thị·đối tượng ma
Yếu tố
Mất gói
Ai gặp phải
Chỉ mình tôi
Khi nào
Sau khi để yên một lúc, Ngay sau đăng nhập hoặc bảo trì
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), Hạ tầng server (Đội hạ tầng)
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 (chỉnh TCP_KEEPIDLE, TCP_USER_TIMEOUT); khi người chơi kết nối lại, dùng session token để thay phiên cũ và nối tiếp. Client: gửi heartbeat ở tầng game cách vài giây đến vài chục giây một lần (bằng hoặc ngắn hơn một nửa idle timeout ngắn nhất), tự động kết nối lại khi bị ngắt.
Việc cần làm (Đội hạ tầng)
Hạ giá trị mặc định của kernel (tcp_keepalive_time, v.v.) cho các socket mà code không tự đặt (chỉ áp dụng cho socket đã bật SO_KEEPALIVE).
Con số tham khảo
Mặc định trên Linux, kết nối nhàn rỗi 7.200 giây thì bắt đầu kiểm tra, gửi 9 probe cách nhau 75 giây, và nếu đến cuối vẫn không có phản hồi thì ngắt kết nối. Cộng lại khoảng 2 giờ 11 phút. Windows mặc định cũng phải nhàn rỗi 2 giờ mới bắt đầu kiểm tra.
Trên đồ thị
Chỉ một phần cao · Thời gian từ lần nhận cuối theo từng kết nối
Chỗ cần xem
lastrcv (số ms từ lần nhận cuối) và timer keepalive (timer:(keepalive,…)) theo từng kết nối qua ss -tnoi, đối chiếu với các lần server game từ chối vì “Tài khoản đang đăng nhập”
Đúng nếu
vẫn còn kết nối ESTABLISHED có lastrcv từ vài phút đến vài giờ, và các lần kết nối lại của tài khoản đó bị từ chối với “Tài khoản đang đăng nhập”
Loại trừ nếu
không có kết nối nào im lặng lâu mà vẫn gặp “Tài khoản đang đăng nhập” → xem code dọn phiên của server game
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. tcp(7) — Linux manual page Linux man-pages
    Sau 7.200 giây nhàn rỗi, gửi 9 probe cách nhau 75 giây (thêm khoảng 11 phút); chỉ áp dụng cho socket đã bật SO_KEEPALIVE; TCP_KEEPIDLE, TCP_USER_TIMEOUT
  2. RFC 9293: Transmission Control Protocol (TCP) IETF
    Keepalive phải tắt theo mặc định, và khoảng nhàn rỗi mặc định phải từ 2 giờ trở lên
  3. SO_KEEPALIVE socket option Microsoft
    Timeout keepalive TCP mặc định của Windows là 2 giờ
  4. ss(8) — Linux manual page iproute2
    lastrcv (số ms từ lần nhận cuối) trong -i, timer:(keepalive,…) trong -o

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 (Không vào được·kẹt loading)

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