Linux 서버에서 TIME_WAIT 연결이 급증하는 원인과 TCP 소켓 고갈 해결 방법
웹서버에서 요청을 처리하는 속도가 갑자기 느려지거나, 외부 API와의 연결이 간헐적으로 실패하는 문제가 발생할 수 있습니다. CPU 사용률이나 메모리 사용량에는 특별한 이상이 없는데도 새로운 네트워크 연결이 제대로 생성되지 않는 경우가 있습니다.
이러한 상황에서 확인해야 할 항목 중 하나가 TCP 연결의 TIME_WAIT 상태입니다.
Linux 서버에서 ss 명령어로 TCP 연결 상태를 조회했을 때 수천 개 또는 수만 개의 TIME_WAIT 연결이 발견되기도 합니다. 특히 짧은 HTTP 요청이 반복되거나, 애플리케이션에서 외부 API 호출을 빈번하게 수행하는 환경에서 이러한 현상이 나타날 수 있습니다.
그러나 TIME_WAIT 연결이 많다는 사실만으로 서버 장애라고 판단해서는 안 됩니다. TIME_WAIT는 TCP 프로토콜이 정상적으로 연결을 종료하기 위해 사용하는 상태이며, 특정 상황에서만 자원 부족이나 연결 실패와 연관됩니다.
이번 글에서는 Linux 서버에서 TIME_WAIT가 발생하는 원인과 TCP 연결 종료 과정을 살펴보고, 실제 장애 분석에 필요한 명령어와 해결 방법을 정리합니다.
원인
TIME_WAIT 상태가 발생하는 이유
TCP는 클라이언트와 서버가 연결을 수립한 후 데이터를 주고받는 연결 지향 프로토콜입니다.
데이터 전송이 끝났다고 해서 TCP 연결이 즉시 완전히 사라지는 것은 아닙니다.
TCP는 연결을 종료하는 과정에서 FIN과 ACK 패킷을 주고받으며, 정상적인 연결 종료 절차를 완료한 후에도 일정 시간 동안 연결 정보를 유지할 수 있습니다.
이때 등장하는 상태가 TIME_WAIT입니다.
일반적으로 TCP 연결을 먼저 종료하는 측이 정상적인 종료 절차를 거쳐 TIME_WAIT 상태에 진입합니다.
예를 들어 애플리케이션 서버가 외부 API 서버에 요청을 보내고 응답을 받은 뒤 TCP 연결을 먼저 종료한다면, 애플리케이션 서버에 TIME_WAIT 항목이 남을 수 있습니다.
반대로 외부 API 서버가 먼저 연결을 종료한다면 TIME_WAIT는 상대편에서 발생할 수 있습니다.
따라서 TIME_WAIT가 발생하는 위치는 단순히 클라이언트인지 서버인지에 따라 결정되는 것이 아니라, 어느 쪽이 먼저 연결을 종료했는지에 영향을 받습니다.
짧은 TCP 연결이 반복되는 환경
TIME_WAIT가 많이 발생하는 대표적인 원인은 짧은 TCP 연결의 반복 생성입니다.
웹 애플리케이션에서 다음과 같은 작업을 수행한다고 가정하겠습니다.
- 외부 REST API 호출
- 데이터베이스 연결 생성과 종료
- 내부 마이크로서비스 간 HTTP 통신
- 원격 서버에 대한 반복적인 HTTP 요청
이 과정에서 기존 TCP 연결을 재사용하지 않고 매번 새로운 연결을 생성하면 연결 수립과 종료가 반복됩니다.
특히 HTTP Keep-Alive나 애플리케이션의 커넥션 풀을 적절하게 사용하지 않는 환경에서는 불필요한 연결 생성이 증가할 수 있습니다.
연결 생성 자체가 문제가 되는 것은 아닙니다. 문제는 짧은 연결이 매우 높은 빈도로 발생하고, 종료된 연결의 TIME_WAIT 정보가 누적되는 상황입니다.
예를 들어 초당 500개의 연결을 종료하고 해당 연결이 평균 60초 동안 TIME_WAIT 상태에 머문다고 가정하면 다음과 같이 계산할 수 있습니다.
초당 종료 연결 수 = 500개
TIME_WAIT 유지 시간 = 60초
예상 TIME_WAIT 연결 수
= 500 × 60
= 약 30,000개
이 계산은 연결 종료율이 일정하고 재사용이나 제한 등의 추가 조건을 고려하지 않은 단순 모델입니다.
실제 Linux 서버에서 관찰되는 수치는 커널 버전, 네트워크 설정, 트래픽 패턴에 따라 달라집니다.
중요한 점은 TIME_WAIT 연결 수가 단순한 동시 접속자 수가 아니라, 일정 시간 동안 종료된 TCP 연결의 누적량과 밀접하게 관련된다는 것입니다.
TIME_WAIT와 임시 포트 고갈의 관계
클라이언트가 서버에 TCP 연결을 생성할 때는 일반적으로 로컬 IP 주소와 임시 포트가 사용됩니다.
예를 들어 다음과 같은 연결이 생성될 수 있습니다.
192.168.0.10:40001 → 203.0.113.20:443
192.168.0.10:40002 → 203.0.113.20:443
192.168.0.10:40003 → 203.0.113.20:443
여기서 40001, 40002, 40003은 로컬 시스템에서 사용하는 포트 번호입니다.
Linux는 새 연결을 생성할 때 사용 가능한 임시 포트를 선택합니다.
특정 목적지로 짧은 연결을 매우 빠르게 반복하고 기존 연결의 TIME_WAIT 정보가 누적되면 새 연결에 사용할 수 있는 포트 조합이 부족해질 수 있습니다.
다만 TIME_WAIT 항목 하나가 모든 목적지에 대한 포트 하나를 무조건 점유하는 것은 아닙니다.
TCP 연결은 출발지 IP, 출발지 포트, 목적지 IP, 목적지 포트의 조합으로 구분되며, Linux의 포트 재사용 여부는 연결 조건과 커널 정책에 따라 달라집니다.
따라서 TIME_WAIT 수가 임시 포트 범위보다 많다고 해서 포트 고갈이 반드시 발생했다고 볼 수는 없습니다.
동작 원리
TCP 연결 종료 과정
TCP 연결 종료는 일반적으로 FIN과 ACK를 교환하는 과정으로 이루어집니다.
정상적인 연결 종료에서 한쪽이 먼저 연결을 종료하는 경우, 대표적인 상태 흐름은 다음과 같습니다.
TCP의 일반적인 능동 종료 흐름을 단순화한 개념도. 동시 종료나 RST 등 다른 종료 경로에서는 상태 전이가 달라질 수 있습니다.
연결을 먼저 종료하는 측은 FIN 패킷을 전송하고 FIN_WAIT_1 상태로 이동합니다.
상대방이 FIN에 대한 ACK를 전송하면 FIN_WAIT_2 상태가 됩니다.
이후 상대방도 FIN 패킷을 전송하면, 먼저 종료를 시작한 측은 해당 FIN을 수신하고 ACK를 전송합니다.
마지막 ACK를 전송한 뒤에는 TIME_WAIT 상태로 이동합니다.
TIME_WAIT는 TCP 연결을 완전히 제거하기 전 안전한 종료를 보장하기 위한 단계입니다.
TIME_WAIT가 필요한 이유
TIME_WAIT가 존재하는 중요한 이유는 두 가지입니다.
첫 번째는 마지막 ACK가 손실된 상황에 대응하기 위해서입니다.
TCP 연결 종료 과정에서 마지막 ACK가 네트워크에서 사라질 수 있습니다.
이 경우 상대방은 자신의 FIN이 정상적으로 처리되지 않았다고 판단하고 FIN 패킷을 재전송할 수 있습니다.
TIME_WAIT 상태를 유지하는 측은 재전송된 FIN에 대응하여 ACK를 다시 보낼 수 있습니다.
두 번째는 이전 연결에서 지연된 패킷이 새로운 연결에 영향을 미치는 위험을 줄이기 위해서입니다.
네트워크에서는 전송된 패킷이 지연되거나 중복되어 도착할 수 있습니다.
이전 TCP 연결과 동일한 주소 및 포트 조합을 사용하는 새로운 연결이 너무 빠르게 생성되면, 오래된 패킷이 새로운 연결에 혼입되는 문제가 발생할 가능성이 있습니다.
TIME_WAIT는 이러한 문제를 방지하기 위한 TCP의 보호 메커니즘입니다.
TIME_WAIT는 얼마나 유지될까?
TIME_WAIT의 유지 시간은 TCP의 MSL(Maximum Segment Lifetime) 개념과 관련됩니다.
전통적인 TCP 모델에서는 TIME_WAIT 상태를 2×MSL 동안 유지하도록 설명합니다.
하지만 모든 운영체제와 Linux 버전에서 TIME_WAIT 유지 시간이 동일한 것은 아닙니다.
현대 Linux에서는 일반적인 TIME_WAIT 처리에 약 60초가 사용되지만, 이를 모든 환경에서 변경 가능한 고정 설정값으로 이해해서는 안 됩니다.
또한 net.ipv4.tcp_fin_timeout은 일반적인 TIME_WAIT 유지 시간을 조정하는 설정이 아닙니다.
이 설정은 다른 TCP 종료 상태와 관련되므로 TIME_WAIT 감소를 목적으로 무작정 변경하는 것은 적절하지 않습니다.
실제 증상
외부 API 연결이 간헐적으로 실패하는 현상
애플리케이션 서버에서 외부 API를 빈번하게 호출하는 상황을 가정하겠습니다.
평상시에는 API 응답이 정상적으로 반환되지만 요청량이 증가하면서 일부 요청에서 연결 실패가 발생할 수 있습니다.
이때 다음과 같은 오류가 나타날 수 있습니다.
java.net.BindException:
Cannot assign requested address
또는 Python 애플리케이션에서는 다음 오류가 발생할 수 있습니다.
OSError: [Errno 99]
Cannot assign requested address
이는 로컬 주소나 포트 할당에 실패했을 때 나타날 수 있는 오류입니다.
다만 이 메시지가 발생했다고 해서 원인이 반드시 TIME_WAIT라고 단정할 수는 없습니다.
잘못된 로컬 IP 바인딩, 네트워크 설정 문제 등 다른 원인도 존재하기 때문입니다.
실제 장애 분석에서는 해당 오류가 발생한 시점에 임시 포트 사용 현황과 TCP 연결 상태를 함께 조사해야 합니다.
트래픽 증가 후 연결 수가 줄어들지 않는 현상
짧은 TCP 연결이 반복되는 서버에서는 트래픽이 감소한 후에도 TIME_WAIT 연결이 일정 시간 유지됩니다.
예를 들어 부하 테스트를 종료했는데도 ss 명령어에서 많은 TIME_WAIT 항목이 조회될 수 있습니다.
이러한 현상은 TCP 연결 종료 과정에서 발생하는 정상적인 동작일 수 있습니다.
TIME_WAIT 연결이 많다는 사실만으로 메모리 누수나 소켓 누수가 발생했다고 판단해서는 안 됩니다.
중요한 것은 새로운 연결 생성이 정상적으로 이루어지고 있는지, 그리고 TIME_WAIT 수가 예상한 트래픽 패턴에 부합하는지를 함께 확인하는 것입니다.
TCP 상태별 증상 비교
| TCP 상태 | 의미 | 주요 점검 사항 |
|---|---|---|
| ESTABLISHED | 연결이 수립된 상태 | 정상 연결 수와 장시간 유지 연결 |
| TIME_WAIT | 연결 종료 후 대기 상태 | 짧은 연결 생성 빈도, 포트 고갈 여부 |
| CLOSE_WAIT | 상대방의 종료 요청을 받은 상태 | 애플리케이션의 소켓 종료 처리 |
| FIN_WAIT_1 | FIN 전송 후 응답 대기 | 종료 과정 및 패킷 흐름 |
| FIN_WAIT_2 | 상대방의 FIN 대기 | 상대방의 종료 처리 지연 |
| SYN_SENT | 연결 요청 후 응답 대기 | 네트워크 연결과 서버 응답 |
특히 CLOSE_WAIT와 TIME_WAIT는 원인과 해결 방법이 다릅니다.
CLOSE_WAIT가 계속 누적된다면 애플리케이션이 연결 종료를 제대로 처리하지 않는 문제를 의심할 수 있습니다.
반면 TIME_WAIT는 정상적으로 연결을 종료한 뒤에도 나타날 수 있습니다.
분석 방법
ss 명령어로 TCP 연결 상태 확인
Linux에서는 ss 명령어를 사용하여 TCP 소켓 상태를 확인할 수 있습니다.
먼저 전체 소켓 통계를 조회합니다.
ss -s
이 명령어는 TCP 연결 상태와 전체 소켓 현황을 요약하여 출력합니다.
TIME_WAIT 항목만 확인하려면 다음 명령어를 사용합니다.
ss -tan state time-wait
옵션의 의미는 다음과 같습니다.
| 옵션 | 의미 |
|---|---|
| -t | TCP 소켓 조회 |
| -a | 전체 상태의 소켓 조회 |
| -n | 포트 및 주소를 숫자로 표시 |
| state time-wait | TIME_WAIT 상태만 필터링 |
TIME_WAIT 연결 수만 계산하려면 다음 명령어를 사용할 수 있습니다.
ss -Htan state time-wait | wc -l
-H 옵션은 헤더를 제거합니다.
따라서 출력 결과의 줄 수를 계산하여 현재 조회된 TIME_WAIT 항목 수를 파악할 수 있습니다.
이 결과는 명령 실행 시점의 스냅샷이며, 이후에도 동일한 수가 유지된다는 의미는 아닙니다.
TCP 상태별 연결 수 집계
전체 TCP 연결이 어떤 상태에 분포하는지 확인하는 것도 중요합니다.
다음 명령어를 사용할 수 있습니다.
ss -Htan | awk '{print $1}' | sort | uniq -c | sort -nr
이 명령어는 각 연결의 TCP 상태를 추출한 후 상태별 개수를 계산합니다.
예를 들어 아래와 같은 결과가 출력될 수 있습니다.
30000 TIME-WAIT
1200 ESTAB
80 CLOSE-WAIT
15 FIN-WAIT-2
위 수치는 명령어 출력 형태를 설명하기 위한 가상 예시이며 실제 서버에서 측정한 결과는 아닙니다.
이처럼 상태별 연결 수를 함께 확인하면 특정 TCP 상태가 비정상적으로 증가하는지 파악하기 쉽습니다.
특정 목적지의 TIME_WAIT 연결 확인
외부 API 연결이 문제라면 전체 TIME_WAIT 연결 수보다 특정 목적지에 대한 연결 상태가 더 중요할 수 있습니다.
예를 들어 목적지 IP가 203.0.113.20이고 포트가 443이라면 다음 명령어로 조회할 수 있습니다.
ss -Htan state time-wait \
dst 203.0.113.20 dport = :443
203.0.113.20은 설명을 위한 예시 IP 주소입니다.
실제 분석에서는 문제가 발생하는 API 서버의 IP 주소와 포트를 입력해야 합니다.
출력된 결과를 통해 해당 목적지에 대한 종료 대기 연결이 얼마나 존재하는지 확인할 수 있습니다.
다만 여러 IP를 사용하는 API 서비스에서는 목적지 IP별 연결을 각각 점검해야 합니다.
임시 포트 범위 확인
Linux에서 사용할 수 있는 임시 포트 범위는 다음 명령어로 조회할 수 있습니다.
cat /proc/sys/net/ipv4/ip_local_port_range
예를 들어 다음과 같은 결과가 출력될 수 있습니다.
32768 60999
이는 자동 할당에 사용되는 임시 포트의 시작과 끝 범위를 의미합니다.
위 예시의 포트 개수는 다음과 같습니다.
60999 - 32768 + 1
= 28232개
하지만 이 값이 서버에서 생성할 수 있는 전체 TCP 연결 수의 절대적인 상한은 아닙니다.
실제 연결 가능 수는 목적지 주소와 포트, 로컬 주소, 명시적인 바인딩 사용 여부, 커널의 소켓 재사용 정책에 따라 달라집니다.
따라서 임시 포트 범위와 TIME_WAIT 수를 단순 비교하기보다, 특정 목적지에 연결하는 과정에서 포트 할당 실패가 실제로 발생하는지 확인해야 합니다.
커널의 TIME_WAIT 재사용 설정 확인
TIME_WAIT 재사용과 관련된 대표적인 Linux 설정은 tcp_tw_reuse입니다.
현재 값은 다음 명령어로 조회할 수 있습니다.
sysctl net.ipv4.tcp_tw_reuse
최근 Linux 커널 문서에서 정의한 값은 다음과 같습니다.
| 설정값 | 의미 |
|---|---|
| 0 | TIME_WAIT 재사용 비활성화 |
| 1 | 안전 조건을 만족하는 경우 전역 재사용 허용 |
| 2 | 루프백 트래픽에 한정하여 재사용 허용 |
최근 커널 문서에는 기본값이 2로 설명되어 있습니다. 그러나 배포판 및 커널 버전에 따라 실제 기본값과 지원 기능이 다를 수 있으므로 반드시 운영 중인 서버의 값을 직접 확인해야 합니다.
The Linux Kernel documentation
+1
중요한 점은 tcp_tw_reuse가 TIME_WAIT 연결을 즉시 삭제하는 설정이 아니라는 것입니다.
이 설정은 TCP 프로토콜에서 안전하다고 판단되는 조건에 한하여 TIME_WAIT 소켓의 재사용을 허용하는 기능입니다.
연결 실패와 실제 포트 고갈 여부 확인
TIME_WAIT가 많은 상황에서는 다음 세 가지 항목을 함께 확인하는 것이 좋습니다.
- 애플리케이션 로그에서
EADDRNOTAVAIL또는Cannot assign requested address오류가 발생하는지 - 문제가 발생하는 목적지의 연결 생성 빈도가 비정상적으로 높은지
- 새 TCP 연결 생성이 실제로 실패하거나 지연되는지
필요하다면 다음 명령어로 TCP 관련 커널 통계도 조회할 수 있습니다.
nstat -az
nstat는 커널 네트워크 통계를 조회하는 도구이며, 배포판에 따라 별도 패키지 설치가 필요할 수 있습니다.
이 중 TCP 및 네트워크 연결과 관련된 카운터를 선별하여 증가 추이를 비교하면 연결 실패 원인을 좁히는 데 도움이 됩니다.
해결 방법
HTTP Keep-Alive로 TCP 연결 재사용
TIME_WAIT 누적을 줄이는 가장 기본적인 접근 방법 중 하나는 불필요하게 생성되는 TCP 연결 자체를 줄이는 것입니다.
HTTP 요청마다 TCP 연결을 생성하고 종료하는 대신, 기존 연결을 재사용하면 연결 생성과 종료에 필요한 처리 비용을 줄일 수 있습니다.
HTTP/1.1에서는 지속 연결을 활용할 수 있으며, HTTP/2에서는 하나의 TCP 연결을 통해 여러 요청을 다중화할 수 있습니다.
다만 실제 연결 재사용 여부는 HTTP 클라이언트 구현, 서버 설정, 프록시 구성, 연결 유휴 시간 등에 따라 달라집니다.
HTTP Keep-Alive를 사용한다고 해서 모든 TIME_WAIT가 사라지는 것은 아닙니다.
하지만 짧은 연결이 지나치게 많이 발생하는 환경에서는 연결 재사용이 효과적인 개선책이 될 수 있습니다.
애플리케이션 커넥션 풀 적용
외부 API 호출이 많은 서비스에서는 HTTP 클라이언트의 커넥션 풀을 확인해야 합니다.
예를 들어 요청을 처리할 때마다 새로운 HTTP 클라이언트 객체를 생성하면, 클라이언트 라이브러리의 구성에 따라 연결 재사용이 제대로 이루어지지 않을 수 있습니다.
반대로 장기간 사용할 수 있는 HTTP 클라이언트와 커넥션 풀을 활용하면 기존 연결을 여러 요청에서 재사용할 수 있습니다.
커넥션 풀을 설정할 때는 다음 항목을 고려해야 합니다.
| 설정 항목 | 점검 내용 |
|---|---|
| 최대 연결 수 | 실제 동시 요청량에 적합한지 |
| 목적지별 최대 연결 수 | 특정 API 서버에 연결이 집중되는지 |
| 유휴 연결 유지 시간 | 서버 측 종료 정책과 충돌하지 않는지 |
| 연결 획득 대기 시간 | 풀 고갈 시 요청이 지나치게 대기하지 않는지 |
| 연결 및 읽기 타임아웃 | 장애 상황에서 연결이 과도하게 유지되지 않는지 |
커넥션 풀을 무조건 크게 설정하는 것도 바람직하지 않습니다.
불필요하게 많은 연결을 유지하면 메모리와 파일 디스크립터 사용량이 증가할 수 있기 때문입니다.
적절한 커넥션 풀 크기는 실제 동시 요청량과 대상 서버의 처리 능력을 기준으로 결정해야 합니다.
임시 포트 범위 조정
실제 임시 포트 고갈이 확인되었고 애플리케이션의 연결 재사용만으로 해결하기 어렵다면 임시 포트 범위 조정을 검토할 수 있습니다.
현재 설정을 확인합니다.
sysctl net.ipv4.ip_local_port_range
다음은 범위를 조정하는 명령어의 예시입니다.
sudo sysctl -w \
net.ipv4.ip_local_port_range="10000 65000"
이 값은 모든 서버에 권장되는 기본 설정이 아니라 조정 방법을 설명하기 위한 예시입니다.
실제 운영 서버에서는 이미 사용 중인 서비스 포트, 예약된 포트 범위, 운영체제와 네트워크 환경을 검토해야 합니다.
임시 포트 범위를 확장하더라도 애플리케이션에서 짧은 연결을 무분별하게 생성한다면 근본적인 문제가 남을 수 있습니다.
또한 설정 변경 전후로 연결 실패율과 TCP 연결 상태를 비교해야 합니다.
tcp_tw_reuse 설정 변경 시 주의사항
인터넷에서 TIME_WAIT 해결 방법을 검색하면 다음과 같은 설정을 적용하라는 설명을 접할 수 있습니다.
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
하지만 운영 환경에서 이 명령어를 검증 없이 실행하는 것은 권장하지 않습니다.
Linux 커널 공식 문서 역시 전문가의 검토 없이 해당 값을 변경하지 말 것을 안내합니다.
The Linux Kernel documentation
+1
TIME_WAIT 재사용은 이전 TCP 연결의 패킷과 새로운 연결이 충돌하지 않도록 하는 안전 조건을 고려해야 합니다.
특히 TCP 타임스탬프, 통신 상대방의 구현, NAT 환경 등 다양한 요소가 영향을 줄 수 있습니다.
따라서 다음 순서로 접근하는 것이 적절합니다.
우선 불필요한 TCP 연결 생성을 줄입니다.
그다음 커넥션 풀과 HTTP 지속 연결 설정을 점검합니다.
이후에도 임시 포트 고갈이 반복된다면 커널 버전과 네트워크 환경을 확인한 뒤 TIME_WAIT 재사용 정책을 검토합니다.
커널 설정 변경은 원인을 확인한 후 적용하는 보조적인 해결책으로 접근해야 합니다.
TIME_WAIT를 강제로 제거해야 할까?
TIME_WAIT 수가 많다는 이유만으로 서버를 재시작하거나 TCP 소켓을 강제로 제거하는 것은 일반적인 해결 방법이 아닙니다.
TIME_WAIT는 TCP가 정상적으로 연결을 종료하기 위해 사용하는 상태입니다.
무분별하게 제거하면 연결 종료 안전성을 해칠 수 있으며, 실제로 연결을 과도하게 생성하는 애플리케이션 구조는 그대로 남습니다.
또한 TIME_WAIT 상태의 TCP 항목은 일반적인 ESTABLISHED 연결과 달리 애플리케이션 프로세스에 계속 연결된 파일 디스크립터와 동일하게 취급해서는 안 됩니다.
따라서 TIME_WAIT가 많다고 해서 곧바로 프로세스의 파일 디스크립터가 고갈된 상태라고 판단하는 것도 잘못된 분석입니다.
파일 디스크립터 고갈과 TIME_WAIT로 인한 임시 포트 부족은 서로 다른 자원 문제이며, 각각 별도로 진단해야 합니다.
해결 후 정상 여부 검증
설정을 변경하거나 애플리케이션의 연결 관리 방식을 개선했다면 반드시 변경 전후를 비교해야 합니다.
주요 검증 항목은 다음과 같습니다.
| 검증 항목 | 개선 여부 판단 |
|---|---|
| TIME_WAIT 연결 수 | 동일 트래픽에서 불필요한 누적이 감소했는지 |
| 초당 신규 연결 수 | 연결 재사용으로 생성 빈도가 감소했는지 |
| API 연결 실패율 | 연결 생성 오류가 감소했는지 |
| 응답 시간 | 평균뿐 아니라 상위 지연 구간도 개선됐는지 |
| ESTABLISHED 연결 수 | 연결 풀 도입 후 과도하게 증가하지 않았는지 |
| 파일 디스크립터 사용량 | 연결 유지에 따른 추가 자원 사용이 적절한지 |
TIME_WAIT 수치가 감소하더라도 연결 실패나 응답 지연이 계속된다면 문제의 근본 원인이 다른 곳에 있을 수 있습니다.
반대로 TIME_WAIT 수가 높게 유지되더라도 서비스 응답이 정상적이고 연결 생성에 문제가 없다면 반드시 해당 수치를 낮출 필요는 없습니다.
핵심은 TIME_WAIT 자체를 없애는 것이 아니라 서비스가 안정적으로 TCP 연결을 생성하고 종료할 수 있도록 관리하는 것입니다.
정리
Linux 서버에서 TIME_WAIT 연결이 증가하는 현상은 TCP 연결 종료 과정에서 발생하는 정상적인 동작일 수 있습니다.
특히 짧은 TCP 연결을 반복해서 생성하는 애플리케이션에서는 TIME_WAIT 항목이 빠르게 누적될 수 있습니다.
하지만 TIME_WAIT 연결이 많다는 사실만으로 서버 장애나 소켓 고갈을 단정해서는 안 됩니다.
실제 장애 분석에서는 신규 TCP 연결 생성 실패 여부, 임시 포트 사용 현황, 목적지별 연결 수, 애플리케이션의 커넥션 풀 설정을 종합적으로 확인해야 합니다.
운영 환경에서 기억해야 할 핵심 사항은 다음과 같습니다.
- TIME_WAIT는 TCP 연결 종료의 안전성을 위한 정상적인 상태입니다.
- TIME_WAIT 연결 수는 짧은 연결의 생성 및 종료 빈도와 밀접하게 관련됩니다.
- TIME_WAIT가 많다고 반드시 파일 디스크립터나 임시 포트가 고갈된 것은 아닙니다.
ss명령어를 이용하면 TCP 상태별 연결 현황을 확인할 수 있습니다.- HTTP Keep-Alive와 커넥션 풀을 통한 연결 재사용은 불필요한 신규 연결을 줄이는 효과적인 방법입니다.
tcp_tw_reuse와 같은 커널 설정은 네트워크 환경을 검토한 후 신중하게 변경해야 합니다.
TCP 연결 문제를 해결할 때 가장 중요한 것은 단순히 TIME_WAIT 수치를 줄이는 것이 아니라, 연결이 왜 반복적으로 생성되고 종료되는지 이해하는 것입니다.
서버의 자원 사용량과 실제 연결 실패 현상을 함께 분석하면 불필요한 커널 튜닝을 피하면서도 안정적인 네트워크 처리 구조를 구성할 수 있습니다.




댓글 0
첫 댓글을 남겨보세요.