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

Sách trắng lag game › L7 OS server (kernel)

Giới hạn file descriptor File descriptor limit (ulimit)

ID nguyên nhân so-fd · Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp 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 →

Mỗi kết nối cần một file descriptor (fd, con số OS gán cho mỗi file hoặc socket đang mở), nhưng số fd mà một tiến trình được mở có giới hạn.

Vì sao Số người chơi đồng thời chạm giới hạn file descriptor của tiến trình → Dẫn đến Server không nhận được kết nối mới (Too many open files). Việc mở file log và kết nối DB cũng thất bại theo → Trên màn hình Từ đúng một mức số người nhất định trở đi, mọi người mới vào đều gặp không vào được·kẹt loading

Triệu chứng
Không vào được·kẹt loading
Yếu tố
Mất gói
Ai gặp phải
Cả server
Khi nào
Ngay sau đăng nhập hoặc bảo trì, Khi đông người
Phụ trách
Phụ trách chính Hạ tầng server (Đội hạ tầng) · Phối hợp Phát triển server (Đội phát triển game)
Việc cần làm (Đội phát triển game)
Luôn đóng socket khi kết thúc kết nối (tránh rò rỉ fd); khi accept thất bại với EMFILE (hết fd), tạm dừng nhận kết nối một lúc hoặc dùng một fd dự phòng giữ sẵn để nhận rồi đóng ngay (để server không tốn CPU xử lý lặp đi lặp lại cùng một thông báo kết nối mới).
Việc cần làm (Đội hạ tầng)
Kiểm tra ulimit và cấu hình service (LimitNOFILE của systemd), cảnh báo khi gần chạm giới hạn.
Con số tham khảo
Trên Linux, nếu không cấu hình riêng cho service, giới hạn này vẫn thường là 1.024. Server game thường nâng lên hàng chục nghìn đến hàng trăm nghìn. Windows không có giới hạn mặc định thấp như vậy.
Trên đồ thị
Chạm giới hạn rồi đi ngang · Số fd đang mở của tiến trình, số kết nối đồng thời
Chỗ cần xem
fd-nr (số file descriptor đang mở) của tiến trình server game qua pidstat -v, giới hạn số file mở trong /proc/PID/limits, và các lần accept thất bại (EMFILE, Too many open files) trong log server
Đúng nếu
số fd đi ngang ở đúng giá trị giới hạn, và từ lúc đó accept thất bại với EMFILE
Loại trừ nếu
số fd còn cách xa giới hạn. Yêu cầu kết nối bị kernel bỏ → “Tràn hàng đợi kết nối (backlog)”; vấn đề nằm ở theo dõi kết nối → “Bảng conntrack của server bị đầy”
Cách kiểm tra
Kiểm tra bằng công cụ hạ tầng (không cần code game)
Tìm hiểu thêm
Các kết nối chưa được nhận vẫn nằm nguyên trong hàng đợi kết nối (backlog) của kernel, nên tùy cách viết code, server có thể liên tục nhận thông báo “có kết nối mới” và tốn CPU vô ích.

Nguồn

  1. systemd-system.conf(5) — Linux manual page systemd
    Giá trị mặc định DefaultLimitNOFILE của service là 1024:524288 (giới hạn mềm 1.024)
  2. accept(2) — Linux manual page Linux man-pages
    Khi tiến trình chạm giới hạn fd, accept thất bại với EMFILE
  3. Maximum Number of Sockets Supported Microsoft
    Winsock trên Windows chỉ giới hạn số socket theo bộ nhớ khả dụng
  4. pidstat(1) — Linux manual page sysstat
    fd-nr của -v: số file descriptor mà tiến trình đang mở
  5. proc_pid_limits(5) — Linux manual page Linux man-pages
    /proc/PID/limits chứa giá trị mềm và cứng của từng giới hạn tài nguyên theo tiến trình

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

Cùng tầng: L7 OS server (kernel)

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