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)
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”
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
tcp(7) — Linux manual pageLinux 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