Linux 서버를 운영하다 보면 ss -ant 또는 netstat -ant 명령어를 실행했을 때 수천, 수만 개의 TIME_WAIT 상태를 발견하는 경우가 있습니다. 특히 웹 서버, API 서버, 프록시 서버처럼 짧은 TCP 연결이 빈번하게 생성되는 환경에서는 TIME_WAIT 연결이 급격히 증가할 수 있습니다.
TIME_WAIT가 많다고 해서 반드시 문제가 있는 것은 아니지만, 과도하게 증가하면 포트 고갈(Ephemeral Port Exhaustion), 파일 디스크립터 부족, 새로운 연결 지연 등의 문제가 발생할 수 있습니다.
이번 글에서는 TIME_WAIT 상태가 발생하는 이유와 확인 방법, 최적화 및 해결 방법을 실무 중심으로 알아보겠습니다.
TCP TIME_WAIT란?
TIME_WAIT는 TCP 연결이 정상적으로 종료된 후 일정 시간 동안 연결 정보를 유지하는 상태입니다.
TCP 연결 종료 과정은 다음과 같습니다.
Client Server
FIN --------------------->
<----------------- ACK
<----------------- FIN
ACK --------------------->
│
▼
TIME_WAIT
TIME_WAIT 상태는 마지막 ACK가 제대로 전달되지 않았을 경우를 대비하고, 이전 연결의 지연 패킷이 새로운 연결에 영향을 주지 않도록 하기 위해 존재합니다.
즉, 정상적인 TCP 동작 과정의 일부입니다.
TIME_WAIT가 많아지는 원인
다음과 같은 환경에서는 TIME_WAIT가 자연스럽게 증가합니다.
- 웹 서버
- API 서버
- Nginx Reverse Proxy
- HAProxy
- Kubernetes
- Docker 환경
- 대량의 HTTP 요청 처리
- 짧은 TCP 연결 반복
- KeepAlive 미사용
- 부하 테스트 수행
특히 초당 수천 건 이상의 연결이 발생하는 서비스에서는 매우 흔한 현상입니다.
1. TIME_WAIT 개수 확인하기
현재 TIME_WAIT 연결 수를 확인합니다.
ss -ant | grep TIME-WAIT | wc -l
또는
netstat -ant | grep TIME_WAIT | wc -l
평상시보다 급격히 증가했는지 확인합니다.
2. TCP 연결 상태 확인하기
전체 TCP 상태를 확인합니다.
ss -s
예시
TCP:
estab 450
timewait 15320
closed 120
TIME_WAIT 수가 비정상적으로 많은지 확인합니다.
3. TIME_WAIT를 많이 생성하는 프로세스 확인하기
포트를 기준으로 확인합니다.
ss -tanp
또는
lsof -iTCP
어떤 서비스가 가장 많은 연결을 생성하는지 분석합니다.
4. KeepAlive 설정 확인하기
HTTP KeepAlive를 사용하면 새로운 TCP 연결 생성을 줄일 수 있습니다.
Nginx 예시입니다.
keepalive_timeout 65;
keepalive_requests 1000;
Apache 예시입니다.
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
KeepAlive를 적절히 설정하면 TIME_WAIT 발생을 크게 줄일 수 있습니다.
5. Ephemeral Port 범위 확인하기
사용 가능한 임시 포트를 확인합니다.
sysctl net.ipv4.ip_local_port_range
예시
32768 60999
필요하다면 범위를 늘릴 수 있습니다.
sysctl -w net.ipv4.ip_local_port_range="10240 65535"
6. tcp_fin_timeout 확인하기
FIN 상태 유지 시간을 확인합니다.
sysctl net.ipv4.tcp_fin_timeout
예시
60
필요 시 조정할 수 있습니다.
sysctl -w net.ipv4.tcp_fin_timeout=30
단, 지나치게 낮추면 정상 연결 종료에 영향을 줄 수 있습니다.
7. KeepAlive 연결 확인하기
현재 KeepAlive 연결을 확인합니다.
ss -tan | grep ESTAB
또는
netstat -an | grep ESTABLISHED
지속 연결이 충분히 활용되고 있는지 확인합니다.
8. 네트워크 성능 확인하기
트래픽 상태를 함께 확인합니다.
sar -n DEV 1
또는
iftop
트래픽 증가와 TIME_WAIT 증가가 동시에 발생하는지 확인합니다.
9. 커널 로그 확인하기
TCP 관련 오류를 확인합니다.
dmesg | grep TCP
또는
journalctl -k | grep tcp
포트 부족이나 연결 관련 오류가 있는지 확인합니다.
10. 파일 디스크립터 확인하기
연결이 많아질 경우 파일 디스크립터 부족 여부도 확인합니다.
ulimit -n
현재 열린 파일 수는 다음 명령으로 확인합니다.
cat /proc/sys/fs/file-nr
TIME_WAIT 증가와 함께 파일 디스크립터 한계에 도달하지 않았는지 점검합니다.
TIME_WAIT 점검 순서
실무에서는 다음 순서대로 확인하는 것이 좋습니다.
- TIME_WAIT 개수 확인
- TCP 연결 상태 확인
- 연결 생성 프로세스 확인
- KeepAlive 설정 점검
- Ephemeral Port 범위 확인
- FIN Timeout 확인
- 네트워크 트래픽 분석
- 커널 로그 확인
- 파일 디스크립터 확인
- 성능 테스트 후 설정 적용
TIME_WAIT 사용 시 주의사항
다음 사항을 고려해야 합니다.
- TIME_WAIT는 정상적인 TCP 동작이다.
- 단순히 개수가 많다고 문제는 아니다.
- KeepAlive를 적극 활용한다.
tcp_tw_recycle은 제거된 옵션이므로 사용하지 않는다.- 최신 커널에서는 기본 TCP 동작을 유지하는 것이 안전하다.
- 실제 병목이 발생하는지 먼저 확인한 후 튜닝한다.
무조건 TIME_WAIT를 줄이려고 하기보다, 애플리케이션의 연결 방식과 트래픽 패턴을 먼저 분석하는 것이 중요합니다.
자주 묻는 질문
TIME_WAIT가 많으면 서버에 문제가 있는 건가요?
아닙니다. 트래픽이 많은 서버에서는 매우 흔한 현상입니다. CPU, 메모리, 포트 부족 등의 실제 문제가 없다면 정상일 가능성이 높습니다.
TIME_WAIT를 강제로 제거할 수 있나요?
권장되지 않습니다. TIME_WAIT는 TCP 프로토콜의 안정성을 위해 필요한 상태이며, 임의로 제거하면 패킷 충돌이나 연결 오류가 발생할 수 있습니다.
TIME_WAIT를 줄이는 가장 좋은 방법은 무엇인가요?
KeepAlive를 활성화하여 새로운 TCP 연결 생성을 줄이고, 애플리케이션에서 불필요한 연결을 반복 생성하지 않도록 개선하는 것이 가장 효과적인 방법입니다.
마무리
TCP TIME_WAIT는 정상적인 연결 종료 과정에서 발생하는 TCP 상태이며, 많은 연결을 처리하는 서버에서는 자연스럽게 증가할 수 있습니다. ss, netstat, sysctl, sar 등을 활용해 원인을 분석하고, KeepAlive 설정과 포트 범위 조정 등을 통해 필요한 경우에만 최적화하는 것이 안정적인 서버 운영에 도움이 됩니다.