Linux 서버를 운영하다 보면 ss -ant 또는 netstat -ant 명령을 실행했을 때 FIN_WAIT1, FIN_WAIT2 상태의 TCP 연결이 평소보다 많이 쌓여 있는 것을 볼 수 있습니다. 이러한 상태는 TCP 연결 종료 과정에서 발생하는 정상적인 단계이지만, 특정 환경에서는 수천 개 이상 누적되어 서버 자원을 소모하고 새로운 연결 처리에 영향을 줄 수 있습니다.
특히 웹 서버, API 서버, 프록시 서버, 데이터베이스 서버에서는 FIN_WAIT 상태가 비정상적으로 증가하는 경우 원인을 분석하고 적절한 조치가 필요합니다.
이번 글에서는 FIN_WAIT1과 FIN_WAIT2의 의미, 발생 원인, 확인 방법, 해결 방법을 실무 중심으로 알아보겠습니다.
TCP FIN_WAIT1 / FIN_WAIT2란?
TCP 연결 종료 과정은 다음과 같습니다.
Client Server
FIN ----------------------->
(Client : FIN_WAIT1)
<------------------ ACK
(Client : FIN_WAIT2)
<------------------ FIN
ACK ----------------------->
FIN_WAIT1
애플리케이션이 연결 종료를 요청(FIN 전송)한 후 상대방의 ACK를 기다리는 상태입니다.
FIN_WAIT2
상대방이 ACK를 보냈지만 아직 자신의 FIN 패킷을 보내지 않은 상태입니다.
즉, 상대방이 연결을 완전히 종료하기를 기다리는 단계입니다.
FIN_WAIT 상태가 많아지는 원인
대표적인 원인은 다음과 같습니다.
- 상대 서버의 응답 지연
- 네트워크 장애
- 방화벽 문제
- 애플리케이션 버그
- KeepAlive 설정 문제
- Proxy 연결 문제
- 비정상적인 클라이언트 종료
- 장시간 연결 유지
1. FIN_WAIT 연결 개수 확인하기
현재 FIN_WAIT 상태를 확인합니다.
ss -ant | grep FIN-WAIT
또는
netstat -ant | grep FIN_WAIT
개수만 확인하려면 다음 명령을 사용합니다.
ss -ant | grep FIN-WAIT | wc -l
2. FIN_WAIT1과 FIN_WAIT2 구분하기
각 상태를 따로 확인합니다.
ss -ant | grep FIN-WAIT-1
ss -ant | grep FIN-WAIT-2
어느 상태가 많이 발생하는지 먼저 확인하는 것이 중요합니다.
3. TCP 연결 상태 확인하기
전체 TCP 상태를 확인합니다.
ss -s
또는
netstat -s
ESTABLISHED, TIME_WAIT, CLOSE_WAIT와 함께 비교하여 분석합니다.
4. 어떤 프로세스인지 확인하기
어떤 프로그램이 FIN_WAIT를 생성하는지 확인합니다.
ss -tanp
또는
lsof -iTCP
웹 서버인지, 애플리케이션인지, 데이터베이스인지 원인을 파악합니다.
5. tcp_fin_timeout 확인하기
FIN_WAIT2 유지 시간을 확인합니다.
sysctl net.ipv4.tcp_fin_timeout
예시
net.ipv4.tcp_fin_timeout = 60
필요 시 조정합니다.
sysctl -w net.ipv4.tcp_fin_timeout=30
영구 적용은 /etc/sysctl.conf에 추가합니다.
net.ipv4.tcp_fin_timeout = 30
적용합니다.
sysctl -p
※ 너무 낮게 설정하면 정상 연결 종료에 영향을 줄 수 있으므로 주의해야 합니다.
6. KeepAlive 설정 확인하기
KeepAlive가 적절히 설정되어 있는지 확인합니다.
Nginx 예시
keepalive_timeout 65;
Apache 예시
KeepAlive On
KeepAliveTimeout 5
짧은 연결이 반복될 경우 KeepAlive를 적절히 사용하는 것이 도움이 됩니다.
7. 네트워크 상태 확인하기
인터페이스 상태를 확인합니다.
sar -n DEV 1
또는
ip -s link
패킷 손실이나 오류가 증가하는지 함께 확인합니다.
8. 패킷 캡처하기
FIN 패킷이 정상적으로 오가는지 확인합니다.
tcpdump -i eth0 tcp
또는 특정 포트를 확인합니다.
tcpdump -i eth0 port 80
FIN 패킷이 정상적으로 교환되지 않는다면 네트워크 장비나 방화벽 문제일 가능성이 있습니다.
9. 커널 로그 확인하기
TCP 관련 오류를 확인합니다.
dmesg | grep TCP
또는
journalctl -k | grep tcp
네트워크 오류나 드라이버 문제도 함께 확인합니다.
10. 애플리케이션 로그 확인하기
애플리케이션 로그를 확인하여 연결 종료 관련 오류가 있는지 분석합니다.
예를 들어 Nginx는 다음과 같이 확인할 수 있습니다.
journalctl -u nginx
Tomcat은 다음과 같습니다.
journalctl -u tomcat
애플리케이션에서 연결 종료를 제대로 처리하지 못하는 경우가 있는지 확인합니다.
FIN_WAIT 점검 순서
실무에서는 다음 순서대로 점검하는 것이 좋습니다.
- FIN_WAIT 개수 확인
- FIN_WAIT1과 FIN_WAIT2 구분
- 전체 TCP 상태 확인
- 원인 프로세스 확인
- tcp_fin_timeout 확인
- KeepAlive 설정 확인
- 네트워크 상태 확인
- 패킷 캡처
- 커널 로그 확인
- 애플리케이션 로그 확인
FIN_WAIT 사용 시 주의사항
다음 사항을 고려해야 합니다.
- FIN_WAIT는 정상적인 TCP 종료 과정이다.
- FIN_WAIT2가 과도하게 오래 유지되면 원인을 분석해야 한다.
- tcp_fin_timeout을 과도하게 낮추지 않는다.
- KeepAlive를 적절히 활용한다.
- 방화벽과 로드밸런서 설정도 함께 확인한다.
- 애플리케이션 로그를 반드시 분석한다.
커널 튜닝보다 애플리케이션과 네트워크 환경 분석이 우선입니다.
FIN_WAIT와 CLOSE_WAIT의 차이
| 상태 | 의미 | 주요 원인 |
|---|---|---|
| FIN_WAIT1 | FIN 전송 후 ACK 대기 | 정상 종료 과정 |
| FIN_WAIT2 | ACK 수신 후 상대 FIN 대기 | 상대 종료 지연 |
| CLOSE_WAIT | 상대 FIN 수신 후 애플리케이션 close() 대기 | 애플리케이션 문제 |
CLOSE_WAIT는 애플리케이션 문제인 경우가 많고, FIN_WAIT는 네트워크나 상대 서버의 영향을 받는 경우가 많습니다.
자주 묻는 질문
FIN_WAIT 상태가 많으면 문제가 있는 건가요?
반드시 그렇지는 않습니다. 트래픽이 많은 서버에서는 일시적으로 증가할 수 있습니다. 다만 지속적으로 많은 상태가 유지된다면 원인을 분석해야 합니다.
tcp_fin_timeout을 낮추면 무조건 좋은가요?
아닙니다. 너무 낮게 설정하면 정상적인 TCP 연결 종료 과정에 문제가 생길 수 있습니다. 서비스 환경에 맞게 신중하게 조정해야 합니다.
FIN_WAIT와 TIME_WAIT 중 어느 것이 더 위험한가요?
TIME_WAIT는 정상적인 종료 과정의 일부이며 일반적으로 문제가 아닙니다. FIN_WAIT2가 장시간 유지된다면 상대 서버나 네트워크 환경에 문제가 있을 가능성이 있으므로 점검이 필요합니다.
마무리
TCP FIN_WAIT1과 FIN_WAIT2는 TCP 연결 종료 과정에서 발생하는 정상적인 상태입니다. 그러나 장시간 유지되거나 과도하게 증가하면 네트워크 지연, 애플리케이션 문제, KeepAlive 설정, 방화벽 정책 등을 함께 점검해야 합니다. ss, tcpdump, sysctl, journalctl 등을 활용하여 원인을 정확히 분석하면 안정적인 TCP 연결 관리와 서버 운영이 가능합니다.