Linux TCP TIME_WAIT가 너무 많을 때 원인 분석 및 해결 방법

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 점검 순서

실무에서는 다음 순서대로 확인하는 것이 좋습니다.

  1. TIME_WAIT 개수 확인
  2. TCP 연결 상태 확인
  3. 연결 생성 프로세스 확인
  4. KeepAlive 설정 점검
  5. Ephemeral Port 범위 확인
  6. FIN Timeout 확인
  7. 네트워크 트래픽 분석
  8. 커널 로그 확인
  9. 파일 디스크립터 확인
  10. 성능 테스트 후 설정 적용

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 설정과 포트 범위 조정 등을 통해 필요한 경우에만 최적화하는 것이 안정적인 서버 운영에 도움이 됩니다.

댓글 남기기