Linux Performance
지난번에 nginx upstream keepalive에 대해 짧게 다뤘었는데요 (https://brunch.co.kr/@alden/11), 그 이후로 약간의 업데이트 내용이 있어서 정리합니다.
nginx 의 upstream에 keepalive 지시자를 적용했는데도, tomcat으로의 내부 통신에 time_wait 상태의 소켓이 많이 보였습니다. 이상하다.. 분명히 netty 서버와의 통신에서는 전혀 문제가 없던 설정이었는데 말이죠.. 그래서 tcpdump를 통해서 확인해 보았습니다.
분명 handshake를 맺고 그 후로 정상적으로 잘 통신하는 것 같습니다. 문제는 없어 보이는데요.. 조금 더 덤프 내용을 내려 보면 아래와 같이 tomcat 쪽에서 먼저 연결을 끊기 위해 FIN을 호출하는 것을 볼 수 있습니다.
음? 이상하다는 생각이 들었습니다. 되거나 안되거나 둘 중 하나여야 하는 거 아닌가..라는 생각이 들었는데요.. 자세히 살펴보니 nginx로부터 요청을 처리하다가 어느 순간이 되면 연결을 끊는 것을 확인할 수 있었습니다. tomcat 쪽에 뭔가 설정이 더 필요한 것 같다..라고 느낌이 왔습니다.
범인은 tomcat 설정 중에 maxKeepAliveRequests 였습니다. 이 설정은 한 번 열어 놓은 keepalive 세션으로 몇 개까지의 요청을 처리할 것인지를 설정하는 값인데요, 기본값은 100입니다. tomcat 쪽에 별다른 설정을 하지 않고 기본 값으로만 사용하게 된다면, 100개까지의 요청을 처리하고 해당 세션을 종료해 버립니다. 바로 이 값 때문에 nginx와의 upstream keepalive가 유지되지 않고 끊어졌던 겁니다. (자세한 정보는 https://tomcat.apache.org/tomcat-6.0-doc/config/http.html 참고)
이 값을 -1로 설정하면 unlimit가 되고 우리가 원하던 대로 nginx와 세션을 끊지 않고 keepalive 세션을 계속 사용합니다.
netstat으로 보면 내부 통신에 대한 time_wait 소켓은 더 이상 나타나지 않는 것을 확인할 수 있습니다.
역시.. 무엇이든 기본 값을 사용하면 안 되고 주요 설정 값에 대해서는 미리 파악해두고 적용해야 한다는 교훈을 얻게 된 사례였습니다. tomcat와 nginx를 사용하게 된다면 반드시 잊지 말고 maxKeepAliveRequests를 적용하셔서 내부 통신에 대한 성능 최적화를 하시기 바랍니다.