Timeout을 정리하려고 해봤다

Hyemi Noh
7 min readJun 19, 2021

--

최근 Timeout에 대해서 알아볼 일이 있었다. 인터넷에 있는 자료를 찾아봐도 여전히 헷갈리는 부분이 있어 직접 정리 해보고자 했다. 물론 깔끔한 정리는 실패했다. 그래도 깨달은 부분이 있어 글을 작성해봤다. 각각의 Timeout에 대한 정확한 의미보다는 connection을 established 하기 전에 발생할 수 있는 timeout인지, connection을 맺은 이후 발생할 수 있는 timeout인지에 초점을 더 맞추면서 읽는 걸 추천한다

본격적으로 timeout을 살펴보기 전에 timeout을 이해하기 위해 필수인 3 Way-Handshake를 간단하게 이해해보자.

3 Way-Handshake

  • client와 server가 본격적으로 데이터에 대한 요청과 응답을 주고 받기 전에 연결을 맺는 과정이다.
  • 더 자세한 내용이 궁금하면 구글에 검색해보자.
  • 아래 그림에는 연결을 종료할 때 맺는 과정인 4 Way-Handshake도 나오는데 이는 일단 무시하자. (close와 FIN이 나오는 부분)
https://velog.io/@jyongk/TCP%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B3%B4%EC%9E%A5%EC%84%B1-%EB%8C%80%ED%95%B4-%ED%8C%8C%ED%97%A4%EC%B3%90%EB%B3%B4%EC%9E%90-m0k4vchxup

Timeout은 왜 있을까?

  • 만약 server가 SYN에 ACK를 보내지 않거나 data에 패킷을 보내는 도중 갑자기 보내지 않는다면 client는 계속 기다려야할까?
  • 반대로 client가 connection만 established 하고 request를 보내지 않는다면 server는 계속 기다려야할까?
  • 이런 문제를 해결하기 위해 timeout이 있다.
  • timeout의 핵심은 client이든 server이든 ‘내 리소스 낭비하면서 상대방을 마냥 기다릴 수는 없잖아?’에서 나온 개념으로 보면 될 것 같다.

Connection Timeout

  • connection이 established 될 때까지 기다리는 시간이다.
  • 위의 그림을 참고해보면 SYN을 보내고 상대방에게서 ACK가 올 때까지 기다리는 시간이다.
  • client 라이브러리를 쓴다면 connectionTimeout=1.0이런 식으로 해당 값을 인자로 넘겨주는 경우가 많다. 반면 server는 그렇지 않은 경우도 있다.

Socket Timeout

https://packetlife.net/blog/2010/jun/17/tcp-selective-acknowledgments-sack/
  • connection 맺어지고 난 이후 발생할 수 있는 타임아웃이다.
  • client의 요청에 대해 server는 데이터를 한 번에 보내는 것이 아니라 위의 그림처럼 여러 개의 패킷으로 나누어서 보내게 된다.
  • 이때 각 패킷이 도착한 시간의 차이가 지정한 시간을 넘어가면 socket timeout이 발생한다.
  • 다르게 설명하면 도착한 패킷을 저장하는 곳에서 더 이상 읽을 패킷이 없는 상태가 지정한 시간을 넘어가면 발생하는 것이다.

Read Timeout

  • socket timeout과 비슷하다.
  • 자바에서는 read timeout이 발생하면 socket timeout exception을 발생시킨다.
  • 단 사용하는 라이브러리가 application layer의 protocol을 사용한다면 패킷 단위가 아닌 단순히 데이터 읽기 요청에 대한 timeout일 수 있으니 문서를 잘 살펴보자.

Request Timeout

  • server 입장에서 사용하는 용어인 것 같다.
  • 서로 간에 connection을 맺은 이후, server가 일정 시간동안 client가 request를 보내지 않는다면 connection을 사용하지 않는다고 판단해 connection을 끊는 것이다.
  • request timeout이 발생할 수 있는 이유는 client가 3 way-handshake만 맺고 server에 request는 보내지 않을 수 있기 때문이다. 서버 공격에 사용되는 방법이기도 하다.

한계

  • client 같은 경우 라이브러리를 쓰다보면 인자로 명확하게 connection timeout, socket timeout이라고 나오지만 서버 같은 경우 그렇지 않을 수도 있다.
  • 예를 들면 Apache는 설정 파일에 TimeOut 이라고만 나와있는데 아래와 같이 다양한 상황에서 쓰일 수 있다고 설명하고 있다.

The TimeOut directive defines the length of time Apache httpd will wait for I/O in various circumstances.

When reading data from the client, the length of time to wait for a TCP packet to arrive if the read buffer is empty.

When writing data to the client, the length of time to wait for an acknowledgement of a packet if the send buffer is full.

  • Apache Tomcat은 connectionTimeout을 connection을 맺은 이후 client가 request를 보내지 않을 때 기다리는 시간으로 지정하고 있다. (requestTimeout이랑 비슷함 ㅠ)

The number of milliseconds this Connector will wait, after accepting a connection, for the request URI line to be presented.

  • 또한 client에서도 socket timeout과 read timeout을 섞어서 쓸 수도 있다.

결론

  • 라이브러리, 프레임워크에 따라 의미를 다르게 쓸 수 있다. 그래서 너무 정의 자체에 집착하는 건 추천하지 않는다. 한 번 집착해봤는데 너무 괴로웠다 😢
  • connection을 맺기 전과 connection을 맺은 이후 발생하는 timeout은 구분이 되는 걸 아는 게 가장 중요한 것 같다.
  • 실제로는 사용하는 구현체의 문서를 잘 읽어보고 각각의 인자에 대한 값을 설정하는 게 좋아보인다.

참고

--

--

Hyemi Noh
Hyemi Noh

No responses yet