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

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

Gửi bị chặn (blocking send) do client chậm Blocking send on a full socket

ID nguyên nhân sk-block-send · Phụ trách chính Phát triển server (Đội phát triển game)

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

Khi bộ đệm gửi của một người chơi có đường truyền chậm đã đầy mà server gửi theo kiểu blocking (lời gọi gửi không trả về cho tới khi bộ đệm có chỗ trống), thread của server phải chờ đúng một người đó.

Vì sao Bộ đệm gửi của một client chậm bị đầy → Dẫn đến Vì gửi kiểu blocking nên thread server phải chờ đến khi bộ đệm có chỗ trống → Trên màn hình Mọi người chơi do thread đó phụ trách đều bị đứng hình hoặc quay chậm

Triệu chứng
Đứng hình, Quay chậm
Yếu tố
Ngưng trệ
Ai gặp phải
Một địa điểm hoặc kênh, Cả server
Khi nào
Thỉnh thoảng bất chợt, Khi đông người
Phụ trách
Phụ trách chính Phát triển server (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Gửi non-blocking, đặt giới hạn hàng đợi gửi cho từng client, bỏ các bản cập nhật cũ.
Trên đồ thị
Thỉnh thoảng vọt lên bất chợt · Thời gian tick của server, Send-Q theo từng kết nối
Chỗ cần xem
Các kết nối có Send-Q (số byte chưa nhận được ACK hoặc chưa gửi đi) đã đầy bằng bộ đệm gửi, tìm bằng ss -tn; trong thread dump (stack) của server game lấy lúc tick vọt lên, xem có thread nào đứng ở lời gọi send không
Đúng nếu
khi có kết nối chậm với Send-Q đầy, thread phụ trách kết nối đó đứng ở send, và chỉ những người chơi cùng thread đó bị đứng theo
Loại trừ nếu
thread bị đứng đang chờ ở ngoài send (lock, lời gọi DB) → “Tranh chấp lock”, “Gọi đồng bộ (blocking) trên game thread”
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. send(2) — Linux manual page Linux man-pages
    Khi bộ đệm gửi hết chỗ, send() bị block; ở chế độ non-blocking thì trả về ngay với EAGAIN
  2. send function (winsock2.h) Microsoft
    Winsock cũng vậy, khi bộ đệm hết chỗ thì send bị block, trừ khi đang ở chế độ non-blocking
  3. net/ipv4/tcp_diag.c (Linux v6.12) Linux kernel
    Giá trị Recv-Q và Send-Q trong ss: với socket đang listen là số kết nối chờ accept và giới hạn backlog; với socket đã kết nối là số byte ứng dụng chưa đọc và số byte đã gửi nhưng chưa nhận được ACK

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