[Linux] TCP 소켓 TIME_WAIT 시간 별 리포트

by 스뎅(thDeng) on

API 통신을 많이 하다 보면 소켓이 부족해서 더 이상 접속하지 못 하는 경우가 있다. A서버(웹)에서 B서버(API)로의 호출이 많을 때 서버 호출이 끝난 다음 FIN에 대한 ACK를 받지 못 하면 A서버의 로컬포트는 TIME_WAIT 상태로 대기한다.

TIME_WAIT

ACK를 받지 못 하면 (default) 2분 정도 대기를 하는데, 로컬 포트를 만들 수 있는 개수가 한정되어 있기 때문에 가득 차면 더 이상 API 호출을 할 수 없는 상태가 될 수도 있다.

그렇다면 이렇게 API 호출이 안 되는 현상이 발생했을 때, 이 TIME_WAIT으로 로컬포트가 부족한 상태인지 체크하는 방법은 어떻게 될까?? sar -n SOCK 명령을 실행하면 시간별로 체크해서 수집해둔 소켓 상태를 볼 수 있다. (sar 명령에는 소켓정보 뿐만 아니라 시스템의 여러 정보를 수집하고 볼수 있다. (collect and report) - sar(1) - Linux man page)

$ sar -n SOCK
Linux 3.10.0-693.21.1.el7.x86_64 (my.server.host) 	2018년 05월 03일 	_x86_64_	(2 CPU)
14시 24분 01초    totsck    tcpsck    udpsck    rawsck   ip-frag    tcp-tw
14시 25분 01초       113        10         7         0         0         1
14시 26분 01초       113        10         7         0         0         1
14시 27분 01초       113        10         7         0         0         0
14시 28분 01초       113        10         7         0         0         2
14시 29분 01초       113        10         7         0         0         0
14시 30분 01초       117        11         7         0         0         1
14시 31분 01초       117        11         7         0         0         1

tcp-twTIME_WAIT의 개수이다. 이 개수가 로컬 포트로 사용할 수 있는 범위 개수에 근접했는지 체크하면 된다. 아래 명령 등으로 확인할 수 있고, 이 서버는 28232(= 60999 - 32768 + 1) 만큼 사용할 수 있다.

$ cat /proc/sys/net/ipv4/ip_local_port_range
32768	60999
$ sysctl net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768	60999

해결 방법

이렇게 로컬포트 고갈이 심한 경우는, 간단하게는 keep-alive를 켜서 포트를 재사용하는 방법이 가장 좋다. TIME_WAIT 시간이나 로컬포트 개수를 늘리는 방법도 써봤지만, 그래도 호출이 많으면 가득 차는건 어쩔 수 없다.

참고

별도로 명시하지 않을 경우, 이 블로그의 포스트는 다음 라이선스에 따라 사용할 수 있습니다: Creative Commons License CC Attribution-NonCommercial-ShareAlike 4.0 International License