기술 · 실용 가이드
ulimit을 올렸는데도 Too many open files? Linux 서비스가 닿은 한도를 입증하세요
현재 셸의 ulimit은 실행 중인 서비스의 증거가 아닙니다. 실패 PID로 RLIMIT_NOFILE, 시스템 파일 테이블, inotify를 구분한 뒤 한도를 바꾸세요.

Linux의 “Too many open files” 문구만으로 어떤 한도가 실패했는지 알 수 없습니다. EMFILE은 보통 호출 프로세스의 RLIMIT_NOFILE, ENFILE은 시스템 전체 파일 테이블이며, inotify도 사용자 인스턴스 한도에서 EMFILE을 반환할 수 있습니다.
현재 셸에서 높은 ulimit이 보여도 이미 실행 중인 서비스의 제한은 입증되지 않습니다. 실패 시각과 PID를 보존하고 그 프로세스가 실제 상속한 제한과 FD 수를 읽은 뒤 시스템과 inotify 분기를 확인합니다.
1. 셸이 아니라 실패 프로세스를 보존합니다
재시작 전에 오류 시각과 서비스 PID를 기록합니다. systemd 서비스는 systemctl show UNIT -p MainPID -p LimitNOFILE을 보고 /proc/PID/limits와 /proc/PID/fd를 확인합니다. 나중의 ulimit -n은 관리자 셸과 미래 자식만 설명합니다.
soft와 hard를 분리하고 FD 수를 soft 값과 비교하며 readlink로 일부 대상을 봅니다. lsof -u USER 합계를 한 프로세스의 수로 취급하지 마십시오.
2. EMFILE, ENFILE, inotify를 구분합니다
errno가 있으면 EMFILE은 흔히 RLIMIT_NOFILE, ENFILE은 시스템 파일 테이블입니다. file-nr과 file-max를 비교하고 커널 로그의 file-max reached 신호를 확인합니다. 일반 문구만 보고 file-max를 올리지 마십시오.
watch 생성 실패나 watch 문맥이면 inotify를 확인합니다. inotify_init의 EMFILE은 사용자 인스턴스 한도와 프로세스 FD 한도 모두 가능하며 max_user_instances와 max_user_watches는 별개입니다.
3. 서비스의 상속 경로를 추적합니다
PAM 로그인, 셸, 컨테이너, 애플리케이션 런처, systemd 유닛은 서로 다른 상속 경로입니다. systemd에서는 로드된 유닛과 drop-in을 확인하고 LimitNOFILE 단일 값 또는 soft:hard를 사용합니다.
큰 값을 모든 서비스에 복사하지 마십시오. systemd는 select 사용 프로그램이 1023 초과 FD를 처리하지 못한다고 경고합니다. 지원을 확인하고 로컬 drop-in과 롤백 값을 사용합니다.
4. 정상 동시성과 누수를 구분합니다
한 번의 수치는 정상 여부를 입증하지 못합니다. 같은 PID를 유사 부하에서 반복 측정하고 socket, pipe, 일반 파일, 익명 FD로 묶어 애플리케이션 지표와 비교합니다. 작업 후에도 계속 증가하면 누수 단서입니다.
재시작은 수치를 잠시 낮춰도 원인을 고치지 않습니다. 이전 증거를 보존하고 제한된 정상 상태를 찾으십시오. 특정 FD 종류만 비정상 증가하면 한도보다 소유자를 먼저 고칩니다.
5. 한 소유자만 바꾸고 새 자식을 검증합니다
증거가 가리킨 층만 바꿉니다. 프로세스 제한은 서비스·런처, 누수는 앱, 시스템 테이블은 용량 검토, inotify는 소비자 확인이 우선입니다. 새 자식이 필요하면 한 번 재시작하고 새 PID와 제한을 다시 읽습니다.
성공은 목표 프로세스가 목표 제한을 상속하고 실제 부하에서 여유가 있으며 원래 오류가 사라지는 것입니다. errno가 없거나 소유자가 불명확하거나 nr_open을 넘거나 무한 누수를 숨기면 중지하고 상위 검토로 넘깁니다.
