Watch at Ease세상을 읽고, 일상의 답을 찾다.

기술 · 실용 가이드

Node.js EMFILE: ulimit을 올리기 전에 디스크립터 한도의 소유자를 찾으세요

실패한 프로세스, 상속 한도와 디스크립터 증가를 보존한 뒤 낮은 한도, 누수, 동시성 급증, 감시 압력을 구분합니다.

원본 기술 일러스트: 셸, 서비스, 프로세스와 실시간 사용 증거를 비교합니다.
원본 기술 일러스트: 한도를 바꾸기 전에 디스크립터 경계의 소유자를 찾습니다. Watch at Ease

EMFILE은 튜닝보다 먼저 소유권을 확인할 문제입니다. 대화형 셸, systemd 서비스, 재시작 프로세스의 증거가 다르므로 재시작 전에 PID를 보존하세요.

재시작 전에 실패 프로세스를 고정한다

정확한 명령 또는 서비스, 부모 실행기, PID, 시각과 첫 EMFILE 스택을 기록합니다. 재시작이나 의존성 재설치를 먼저 하면 디스크립터 표가 사라져 안정, 증가, 순간 급증을 구분할 수 없습니다.

프로세스가 실제 상속한 한도를 읽는다

Linux에서 /proc/PID/limits의 Max open files를 읽고 대화형 셸의 ulimit -Sn, -Hn과 비교합니다. 자식은 부모의 한도를 상속하므로 systemd가 서비스를 시작한 뒤 바꾼 셸 설정은 소급 적용되지 않습니다.

현재 디스크립터와 증가를 측정한다

/proc/PID/fd를 여러 번 세고 일반 파일, 소켓, 파이프, 익명 디스크립터로 묶습니다. 일정 한도 근처면 제한, 계속 증가하면 누수, 병렬 작업 때만 치솟으면 동시성 분기를 지지합니다.

감시 압력을 일반 파일과 분리한다

fs.watch나 FSEvent로 끝나는 스택은 감시 표면일 뿐 보편적 해결책의 증거가 아닙니다. 감시 범위, 제외 디렉터리, 프로세스 디스크립터를 비교하고 Linux에서는 별도 inotify 회계도 구분합니다.

올바른 소유자만 한 번 변경한다

서비스의 소프트 한도가 불필요하게 낮으면 실행기나 유닛에서 바꾸고 그 서비스를 재시작합니다. 수가 계속 늘면 닫히지 않은 파일·소켓·감시를 고치고, 급증이면 동시성을 제한합니다. 무관한 셸 한도 변경을 수정이라고 부르지 마세요.

원래 실행기 아래에서 완료를 증명한다

같은 셸, 감독자, CI 또는 서비스 유닛에서 같은 부하를 재실행하고 새 PID 한도, 최고치, 작업 후 기준을 보존합니다. EMFILE이 사라지고 설명 가능한 정상 상태로 돌아와야 완료입니다.

원본 기술 일러스트: 낮은 한도, 누수, 동시성 급증과 감시 압력을 구분합니다.
원본 기술 일러스트: 한 스냅샷으로 네 가지 해결책을 구분합니다. Watch at Ease