본문 바로가기
WAS(tomcat & jetty)

tomcat timeout 설정

by 권성호 2021. 9. 29.

1. 서론

회사 업무 중 클라이언트에서 보내주는 파일을 수신해 저장하는 파일 서버를 개발할 일이 생겼다.

대용량 파일 처리를 위해, 파일 바이너리 데이터를 http프로토콜에서 제공하는 multipart로 송수신하는 것이 아니라 octet-stream 방식 위에 별도의 프로토콜을 만들어 송수신하기로 했다. 

그런데, 고객사로 부터 파일 전송 과정에서 네트워크 대역폭을 일정 수준 이상 넘기지 말아 달라는 요구사항이 있었다. 

이것 때문에 클라이언트에서 파일을 보낼 때 초당 전송량을 계산 후, 임계치가 넘으면 sleep을 하는 과정이 추가되었다.

그런데, 그 과정이 추가된 후 서버와 연동해 보니 서버측에서 에러가 발생했다.

 

서버에서 발생한 오류

 

java.net.SocketTimeoutException에 대해 찾아보았다.

 

http layer에서의 오류라기 보단 tcp layer에서 오류인 것 같다.

handshaking을 통해 connection을 establish하게 되면 클라와 서버 간 내부적으로 socket을 가지고 통신하게 된다.(http 통신도 os관점에서 결국 socket을 가지고 통신하게 된다. )

다시말하면, 서버와 클라 모두 socket을 열어두고 페킷을 주고받는다.

http 요청을 하는 시점에서 서버는 socket을 열어 둔 상태로 클라이언트로부터 페킷이 도착하길 기다리고 있다.

 

이때, 클라가 connection을 수립하기만 하고 페킷을 보내지 않으면 서버는 어떻게 될까?

 

만약 서버가 클라로부터의 페킷을 무한정 기다리게 된다면, socket은 무한정 열려있을 것이고 이는 서버의 리소스 낭비를 의미한다.  따라서 서버 측에선 보통 특정 임계 시간을 설정해 두고 그 시간 동안 클라로부터 어떤 페킷도 도착하지 않으면 connection을 닫도록 구현된다. 

 

java.net.SocketTimeoutException 은 클라로부터 페킷이 임계 시간 동안 도착하지 않았을 경우 발생한다.

 

tomcat connector에 connectionTimeout 설정을 보니 20밀리 초로 되어 있었다. 

이를 2000(2초)로 설정한 후 다시 실행해 보니 에러가 발생하지 않았다.

 

이 에러를 해결하면서 tomcat connector에 timeout과 관련한 다양한 설정이 있다는 것을 알게 되었다.

 

파일 서버를 구현함에 있어,  timeout과 관련해 최적의 설정을 찾을 필요가 있을 것 같아서 관련 내용을 정리해야겠다고 생각했다.

 

 

2. 본론

tomcat과 tomcat connector에 대한 설명은 아래 블로그 참고.....

https://exhibitlove.tistory.com/312

 

[tomcat] 동작원리

출처 : kchanguk.tistory.com/4 1. Tomcat의 설정($TOMCAT_HOME/conf/server.xml)  * server.xml의 역할   TOMCAT의 메인 설정 파일이며 초기 설정을 명세하는 책임이 있습니다.  1) Server   최상위 elemen..

exhibitlove.tistory.com

 

회사 개발 환경은 tomcat connector HTTP/1.1을 사용했기 때문에 그에 대한 timeout설정을 알아보았다.

참고로, timeout의 의미는 아래와 같다.

 

프로그램이 특정한 시간 내에 성공적으로 수행되지 않아서 진행이 자동적으로 중단되는 것

 

1) asyncTimeout

  • tomcat connector는 여러 개가 있는데, 그 모든 connector에 다 포함된 기본 설정
  • 비동기 요청에 대한 기본 timeout 설정
  • 기본 값은 3000ms (30초) => 모든 요청은 기본적으로 30초 이내에 처리되지 않으면 timeout이 발생한다는 의미

2) connectionTimeout

  • [The standard HTTP connectors (NIO, NIO2 and APR/native)]에 포함된 설정
  • connection이 수립된 후, connector가 클라로부터의 페킷을 기다리는 임계 시간 설정
    • request header / body 모두 포함하는 데이터로서의 페킷
    • 요청의 시작부터 끝까지의 시간이 아니라 페킷 단위임에 주의!
  • 기본 값은 60초 / 일반적으로 server.xml에는 20초로 설정되어 있음
  • disableUploadTimeout 이 true로 설정되어 있다면, 해당 timeout은 request body를 읽을 때에도 적용됨

 

3) connectionUploadTimeout

  • [The standard HTTP connectors (NIO, NIO2 and APR/native)]에 포함된 설정
  • 데이터 업로드 작업에서의 timeout을 의미하는 설정(밀리초 단위)
    • 요청의 시작부터 끝까지의 시간이 아니라 페킷 단위임에 주의!
  • disableUploadTimeout 이 false로 설정되어 있을 때만 적용됨

 

4) disableUploadTimeout

  • 일반적인 통신일 때의 timeout 설정과 데이터 업로드를 위한 통신일 때의 timeout 설정을 구분하기 위해 사용
  • true로 설정할 경우
    • 구분하지 않겠다는 의미 => [connectionTimeout == connectionUploadTimeout]이 된다.
  • false로 설정할 경우 
    • 구분하겠다는 의미 
    • connectionTimeout 은 일반적인 요청일 때 그대로 적용되고
    • connectionUploadTimeout은 업로드 요청일 때만 적용

 

disableUploadTimeout을 false로 설정하여 일반적인 요청의 경우 connectionTimeout 시간 설정으로 커버하고, 업로드 요청의 경우만 connectionUploadTimeout으로 처리하자.

즉, 일반적인 요청은 페킷을 기다리는 시간 텀을 작게 하고 업로드의 경우에만 클라에서 sleep 하는 것과 맞춰서 조금 길게 설정하자..

 

 

댓글