TCP연결을 종료하기 위해서는 FIN패킷 교환이 이루어진다. 이때 우아한 종료가 이루어지기 위해서는 총 4번의 패킷교환이 필요하다.
우아한 종료라는 것은 연결된 호스트 양쪽이 모두 연결이 종료되었음을 알게 되는 상태다. 만약 FIN 패킷을 보냈는데, 상대 호스트에서 ACK 패킷을 보내지 않고 종료해버리는 경우 FIN을 보낸측은 우아한 종료를 위해서 일정시간 ACK를 기다리게 된다. 리눅스의 경우 대략 90초 정도를 기다린다. netstat(1)로 확인해 보면 TIME_WAIT인 상태로 나타난다.
TIME_WAIT상태일 경우 해당 포트를 계속 점유하는데, 연결이 빈번한 네트워크 서비스일 경우 연결거부와 관련된 문제가 발생할 수 있다.
TIME_WAIT 문제 발생 상황
mysql의 성능중 처리량을 측정하기 위해서 수백개의 클라이언트로 동접상황을 시뮬레이션 하는 프로그램을 만들어서 테스트하던 중 다음과 같은 문제가 발생했다.
open 파일 제한 갯수
이문제는 /proc/sys/fs/file-max 의 값을 조절하는 걸로 간단히 해결했다.
TIME_WAIT
매우 바쁜 동접테스트 환경을 만들기를 원했다. 이 경우 connect와 close가 빈번하게 발생하는데, TIME_WAIT가 계속 늘어나게 되고 결국에는 할당가능한 PORT를 모두 소비해서 더이상 연결을 할 수 없는 상황이 발생했다.
소프트웨어적인 해결
소켓옵션 변경 : linger
직접 네트워크 프로그램을 제작한다면 가장 좋은 방법일 것이다. 그러나 애플리케이션에서 제공하는 API를 이용한 프로그래밍에는 적용할 수 없다.
예를들어 Mysql DB 성능측정을 위해서, Mysql API를 이용해서 측정 클라이언트를 개발할 경우에는 소켓옵션을 제어할 수가 없다.
다음은 socket 옵션을 이용해서 TIME_WAIT이 발생하지 않도록 하는 코드다.
SO_REUSEADDR 옵션을 사용하면, TIME_WAIT 상태에 있는 PORT를 사용할 수 있다. 서버프로그램이 비정상적으로 종료되건나 클라이언트를 정리하지 않고 종료되면 TIME_WAIT 상태로 넘어간다. 이때 서버 프로그램을 실행시키면 bind() 에러가 발생하는데, 이 옵션을 이용해서 bind()문제를 해결할 수 있다.
[PATCH] networking/ip-sysctl.txt tcp_tw_recycle and tcp_tw_reuse: http://markmail.org/thread/clxtvnfzdgz3cdi4
time-wait recycling vs. reuse: http://www.frameip.com/nntp/comp-protocols-tcp-ip/21912-comp-protocols-tcp-ip-time-wait-recycling-vs-reuse.htm
tcp_tw_reuse, tcp_tw_recycle 적용 사례, Tuning SUSE LINUX Enterprise Server on IBM Eserver xSeries Servers, 28 Page, Figure 1-6 Parameters reuse and recycle enabled (left) and disabled (right): http://www.redbooks.ibm.com/redpapers/pdfs/redp3862.pdf
Contents
TIME_WAIT 에 대해서
TIME_WAIT 문제 발생 상황
소프트웨어적인 해결
소켓옵션 변경 : linger
소켓옵션 변경 : SO_REUSEADDR
커널레벨에서의 해결
client Port range 변경
tcp_fin_timeout
timewait 설정 변경
참고
Recent Posts
Archive Posts
Tags