이 문서를 통해 아래 질문들에 답할 수 있게 됩니다.
File Descriptor Socket 고갈 대응에서 붙잡아야 할 핵심 판단 기준은 무엇인가?열린 자원 고갈은 새 작업 실패로 보인다라는 기준은 어떤 JVM/OS 신호로 확인되는가?- Java/Spring 코드에서
File Descriptor Socket 고갈 대응판단 기준은 어떤 장애 신호로 드러나는가?
개요
이 문서의 주제는 File Descriptor Socket 고갈 대응이다. File descriptor와 socket 고갈 시 확인할 limit, 누수, connection state, 완화 방법을 정리한다.
먼저 붙잡을 기준은 다음 문장이다. 열린 자원 고갈은 새 작업 실패로 보인다. FD limit에 가까워지면 파일 open, socket accept, outbound connect, log file, temp file이 함께 실패할 수 있다.
핵심 모델
- 판단 기준: 열린 자원 고갈은 새 작업 실패로 보인다.
- FD는 socket, regular file, pipe, eventpoll, 로그 파일, temp file을 모두 포함한다.
- 현재 FD 수와 process limit을 함께 봐야 고갈인지 정상 증가인지 판단할 수 있다.
- Socket state는
ESTAB,TIME_WAIT,CLOSE_WAIT, listen backlog를 나눠 봐야 한다. - FD/socket 문제는 inbound 폭주, outbound leak, DB/client pool leak, file close 누락으로 나뉜다.
- 즉시 완화는 유입 제한, leak 경로 차단, 비필수 outbound 호출 중지, limit 조정, 안전한 재시작 순서로 검토한다.
문서별 핵심 구분
- FD 고갈은 파일과 socket 작업을 동시에 실패시킨다.
- 현재 FD 수와 limit, socket state를 함께 본다.
- 누수인지 트래픽 폭주인지 열린 자원 종류로 나눈다.
원리
FD 고갈은 “too many open files” 하나로 끝나지 않는다. 어떤 종류의 FD가 늘었는지 봐야 file close 누락인지, outbound socket leak인지, inbound connection 폭주인지 구분할 수 있다.
Socket 고갈은 상태별로 원인이 다르다. CLOSE_WAIT는 애플리케이션이 close를 하지 못하는 후보이고, TIME_WAIT는 짧은 연결 churn과 관련되며, listen backlog 문제는 새 연결 수락 지연으로 나타난다.
Limit 증설은 완화일 수 있지만 누수를 고치지는 못한다. FD 증가 기울기와 열린 대상 종류를 남겨야 코드 수정, pool 설정, traffic 완화 중 어디로 갈지 결정할 수 있다.
Java/Spring 연결
- Tomcat accept 실패, DB connection 실패, HTTP client connect 실패가 모두 FD 고갈의 표면 증상일 수 있다.
- WebClient/RestTemplate/HTTP client, JDBC pool, Redis client는 outbound socket을 사용한다.
- File upload/download, log appender, temp file, heap dump도 FD와 disk를 함께 사용한다.
CLOSE_WAIT가 쌓이면 response body close 누락, client resource close 누락을 의심한다.- Systemd
LimitNOFILE, container ulimit, process/proc/<pid>/limits를 실제 실행 기준으로 확인한다.
코드와 설정 예시
date -Is
cat /proc/<pid>/limits | grep 'open files'
ls /proc/<pid>/fd | wc -l
ss -antp | grep <pid> | awk '{print $1}' | sort | uniq -c
lsof -p <pid> | awk '{print $5}' | sort | uniq -c | sort -nr | head예시는 limit, 현재 FD 수, socket state, 열린 FD 종류를 한 번에 보는 흐름이다. lsof는 비용이 있을 수 있으므로 장애 중에는 범위를 제한한다.
관찰 명령
ulimit -n
cat /proc/<pid>/limits | grep 'open files'
ls /proc/<pid>/fd | wc -l
ss -s
lsof -p <pid> | headFile Descriptor Socket 고갈 대응 관찰 명령은 결론이 아니라 가설 확인 도구다. 운영 중에는 반복 간격, 대상 PID, 수집 시각을 함께 남기고 출력이 큰 명령은 범위를 제한한다.
지표 해석
| 신호 | 먼저 의심할 것 | 다음 확인 |
|---|---|---|
| FD 수가 limit 근접 | FD 고갈 | /proc/<pid>/limits, /proc/<pid>/fd |
CLOSE_WAIT 증가 | close 누락, stuck socket | socket owner, client close path |
TIME_WAIT 급증 | 짧은 연결 churn | keep-alive, client pool, traffic |
| accept/connect 실패 | backlog, FD, ephemeral port | ss, logs, limit, port range |
FD/socket 분석은 열린 개수, limit, socket state, 실패 로그의 순서를 맞춘다. 새 연결 실패가 먼저였는지, downstream 지연으로 socket이 오래 남았는지에 따라 대응이 달라진다.
장애 상황에서 보는 순서
- 오류 메시지가
Too many open files, connect timeout, accept 실패 중 무엇인지 확인한다. - 현재 FD 수와 process limit을 기록한다.
ss로 socket state 분포를 보고CLOSE_WAIT,TIME_WAIT,ESTAB를 나눈다.lsof나/proc/<pid>/fd로 열린 자원 종류와 대상 host/파일을 샘플링한다.- 유입 제한, outbound 호출 차단, leak endpoint 차단, limit 임시 증설, 재시작을 완화책으로 검토한다.
- 근본 수정은 close 누락, connection pool 설정, keep-alive, timeout, capacity 중 어디인지 나눈다.
Limit을 늘린 뒤에도 열린 FD 증가 기울기가 그대로면 장애는 재발한다. 증설 전후의 증가 속도와 열린 대상 종류를 반드시 남긴다.
실전 팁
lsof전체 출력은 비용이 클 수 있으므로 먼저/proc/<pid>/fd개수와ss -s로 방향을 잡는다.CLOSE_WAIT는 원격이 닫았는데 로컬 애플리케이션이 close하지 못한 상태라는 점을 기억한다.- FD limit 증설은 운영 설정 변경이다. systemd, container, shell limit 중 실제 process에 적용되는 곳을 확인한다.
- Outbound socket leak은 DB/API/Redis client pool metric과 함께 본다.
- File upload나 dump 중에는 FD와 disk가 같이 압박될 수 있다.
주니어 팁
- FD는 파일만 뜻하지 않는다. socket도 FD를 사용한다.
ulimit -n만 보지 말고 실행 중 process의/proc/<pid>/limits를 본다.CLOSE_WAIT와TIME_WAIT는 같은 문제가 아니다.
시니어 팁
- HTTP/DB/Redis client는 반드시 connection pool, timeout, response close 정책을 표준화한다.
- FD budget은 inbound connection, outbound pool, log file, temp file, dump를 합산해 산정한다.
- LB idle timeout, client keep-alive, server keep-alive가 맞지 않으면 socket churn이 증가할 수 있다.
Guru급 팁
- FD 증가 기울기를 보면 누수와 traffic spike를 더 잘 구분할 수 있다. traffic이 줄어도 FD가 내려오지 않으면 누수 쪽이 강하다.
- Socket state는 애플리케이션 코드, kernel timeout, network 장비 설정이 함께 만든 결과다.
- Limit 증설 후에는 FD뿐 아니라 memory, thread, downstream connection limit이 다음 병목이 되는지 확인한다.
위험 신호!
- Process limit 확인 없이
ulimit출력만 믿는다. - FD 수만 보고 socket state와 열린 대상 종류를 보지 않는다.
CLOSE_WAIT가 많은데 client/response close 경로를 확인하지 않는다.- Limit만 늘리고 leak 증가 기울기를 남기지 않는다.
lsof를 무제한 반복 실행해 장애 중 추가 부하를 만든다.
확인 질문
확인 질문
- FD 고갈을 확인할 때
ulimit -n만으로 부족한 이유는 무엇인가?
- Shell limit과 실행 중 process limit이 다를 수 있으므로
/proc/<pid>/limits와 현재 FD 수를 함께 확인해야 한다.CLOSE_WAIT가 많이 쌓일 때 의심해야 할 것은 무엇인가?
- 애플리케이션이 socket이나 response body를 닫지 못하는 close 누락, client resource 관리 문제를 의심해야 한다.
- FD/socket 장애 보고서에 남겨야 할 핵심 증거는 무엇인가?
- FD limit, 현재 FD 수, socket state 분포, 열린 대상 종류, 실패 로그, 적용한 완화와 증가 기울기를 남겨야 한다.