게임 렉 백서 › L7 서버 OS (커널)
파일 디스크립터 한도 File descriptor limit (ulimit)
원인 ID so-fd · 주 담당 인프라팀·서버 인프라 · 함께 게임개발팀·서버 개발
그림과 실험이 있는 원본 카드로 열기 →
연결 하나마다 파일 디스크립터(fd, OS가 열린 파일·소켓에 붙이는 번호)가 필요한데, 한 프로세스가 열 수 있는 fd 수가 제한되어 있습니다.
왜 동접이 프로세스의 파일 디스크립터 한도에 도달 → 그러면 서버가 새 연결을 받지 못함(Too many open files). 로그·DB 연결 열기도 함께 실패 → 화면에서는 정확히 일정 인원부터 아무도 못 들어오는 접속 불가·무한 로딩
- 증상
- 접속 불가·무한 로딩
- 요인
- 손실
- 누가 겪나
- 서버 전체
- 언제
- 접속·점검 직후, 사람이 몰릴 때
- 담당
- 주 담당 인프라팀·서버 인프라 · 함께 게임개발팀·서버 개발
- 게임개발팀 할 일
- 연결을 끝낼 때 소켓을 확실히 닫기(fd 누수 방지), accept가 EMFILE(fd 부족)로 실패하면 잠시 접속 받기를 멈추거나 미리 남겨 둔 예비 fd로 받아 바로 닫기(같은 접속 알림만 반복 처리하며 CPU를 낭비하지 않게).
- 인프라팀 할 일
- ulimit·서비스 설정(systemd의 LimitNOFILE) 확인, 한도 근접 경보.
- 수치 감각
- 리눅스는 서비스 설정을 따로 하지 않으면 한도가 1,024인 경우가 아직 많습니다. 게임 서버는 보통 수만~수십만으로 올립니다. 윈도우에는 이렇게 낮은 기본 한도가 없습니다.
- 그래프에서는
- 한도에 닿아 평평해짐 · 프로세스의 열린 fd 수, 동시 접속 수
- 확인할 곳
- pidstat -v로 게임 서버 프로세스의 fd-nr(열린 파일 디스크립터 수)를, /proc/PID/limits로 열린 파일 수 한도를 보고 서버 로그에서 accept 실패(EMFILE, Too many open files)를 찾음
- 이러면 맞음
- fd 수가 한도 값에서 평평해지고 그 시각부터 accept가 EMFILE로 실패함
- 이러면 아님
- fd 수가 한도에 한참 못 미치면 이 원인이 아님. 접속 요청이 커널에서 버려지면 “접속 대기열(backlog) 넘침”, 연결 추적 쪽이면 “서버 conntrack 테이블 포화”
- 확인 수단
- 인프라 도구로 확인(게임 코드 불필요)
- 더 알아보기
- 받지 못한 접속은 커널 접속 대기열(backlog)에 그대로 남아 있어, 서버 코드에 따라 “새 접속 있음” 알림을 계속 받으며 CPU를 낭비하기도 합니다.
출처
- systemd-system.conf(5) — Linux manual page systemd
서비스의 DefaultLimitNOFILE 기본값은 1024:524288(소프트 한도 1,024) - accept(2) — Linux manual page Linux man-pages
프로세스의 fd 한도에 닿으면 accept가 EMFILE로 실패 - Maximum Number of Sockets Supported Microsoft
윈도우 Winsock은 소켓 수를 사용 가능한 메모리로만 제한 - pidstat(1) — Linux manual page sysstat
-v의 fd-nr: 프로세스가 연 파일 디스크립터 수 - proc_pid_limits(5) — Linux manual page Linux man-pages
/proc/PID/limits에 프로세스별 자원 한도의 소프트·하드 값
함께 보면 좋은 원인
같은 층: L7 서버 OS (커널)
같은 증상(접속 불가·무한 로딩)의 다른 층 원인
그림과 실험이 있는 원본 카드 보기