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
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.