Connection Timeout과 Read Timeout

앵우·2025년 3월 11일
post-thumbnail

Connection Timeout

: 클라이언트와 서버가 연결하는데 소요되는 최대 시간

Read Timeout

: 연결된 클라이언트와 서버가 데이터를 주고 받을 때 소요되는 최대 시간

→ 이 시간들을 넘기게 되면 각각 연결할 수 없는 것으로 그리고 데이터를 받을 수 없는 것으로 판단하고 에러가 발생


Timeout 예시 - 외부 API와 통신하는 상황

  1. 카카오 로그인
  • 클라이언트가 카카오 서버에 사용자 인증 요청을 보낸다. 이때 서버의 응답이 오랜 시간 지연되면 타임아웃 처리될 수 있다.
  1. mysql timeout
  • 스프링 서버가 mysql에 요청을 보낼 때에도 데이터베이스가 응답을 하지 않거나 너무 느리게 응답하면 타임아웃 처리가 발생할 수 있다.

Connection Timeout 값 설정하기

connection timeout에서의 연결은 tcp 3 way handshake를 통해 tcp 연결이 생성되는 것이다.

TCP 3 way handshake

  1. 클라이언트는 서버에 통신을 요청하는 메세지(SYN 패킷)을 보낸다.

  2. 서버는 SYN 요청을 받고 클라이언트에게 요청을 수락한다는 메시지(SYN+ACK)를 보낸다.

  3. 클라이언트는 서버에게 ACK를 보내고 연결이 이루어진다.

고려해볼 수 있는 3가지 사항

  1. SYN 패킷이 유실되었을 때
  2. SYN + ACK 패킷이 유실되었을 때
  3. 마지막 ACK 패킷이 유실되었을 때

❗️타임아웃을 설정하기 전! 기준 정하기

  • 네트워크는 항상 100% 완벽하게 동작하지 않아서 패킷 유실은 꼭 장애 상황이 아니더라도 발생할 수 있다.
  • 네트워크 장애가 발생했다면 가급적 빨리 발견해서 필요한 조치를 취할 수 있어야 한다.
  • 타임아웃 값을 너무 짧게 둔다면?
    • 간헐적으로 발생할 수 있는 패킷 유실에 대해 너무 민감하게 반응하게 된다.
  • 타임아웃 값을 너무 길게 둔다면?
    • 네트워크 장애를 발견하는데 긴 시간이 소요하게 된다.

💫 한 번의 패킷 유실 정도는 재전송을 통해 해결할 수 있는 수준의 타임아웃 값을 설정해보자!


🔎 용어 살펴보가

TCP retransmission

  • TCP는 신뢰성 있는 통신을 위해 자신이 보낸 패킷을 확인한다.
  • client가 보낸 syn에 대한 ack를 받지 못하면 syn을 다시 보낸다.
  • 이는 커널 타이머에 의해 동작

RTO

  • Retransmission Timeout, 재전송 타임아웃 시간
  • RTO를 넘은 시간에도 응답이 오지 않으면 재전송이 이루어지며 RTT를 기반으로 설정

RTT

  • Round Trip Time
  • 두 노드 간에 패킷이 전달되는데 소요되는 시간
  • 패킷이 목적지에 도달하고 나서 해당 패킷에 대한 응답이 출발지로 다시 돌아오기까지의 시간
  • 두 노드 간 거리가 멀면 멀수록 RTT값은 커지며 네트워크 성능 측정을 위한 지표로도 사용

RTO_MIN

  • RTO의 최솟값
  • 기본값은 200ms
  • RTT가 아무리 작아도 RTO는 200ms 밑으로 내려갈 수 없음을 의미

InitRTO

  • 첫번째 SYN 패킷에 대한 RTO

🪄 정리본

~~ 다시 돌아와서 ~~

connection timeout값 하나씩 설정해보기!

단계설명
1. SYN 패킷이 유실되었을 때

- 아직 두 노드간 연결을 맺지 않아 RTT값을 알 수 없으므로 유실된 패킷을 재전송하기 위해 InitRTO값이 필요
- 리눅스에서 하드코딩 되어 있는 1초값으로 사용
2. SYN+ACK 패킷이 유실되었을 때

- 클라이언트는 서버로부터 SYN에 대한 응답으로 ACK를 받지 못하였으므로 TCP retransmission에 따라 클라이언트는 접속을 요청하는 SYN 패킷을 재전송한다.
- 1번 단계와 같이 InitRTO를 적용
3. ACK 패킷을 유실했을 때

- 두 노드가 패킷을 주고 받으면서 둘 사이의 RTT값을 알 수 있게 되었다.
- InitRTO의 적용을 받지 않고 RTT를 기반으로 계산된 RTO를 적용
- RTO_MIN값을 적용하여 200ms 적용

✅ 각 값이 1초를 넘기지 않아 총 경우에 대한 값을 더하여 connection timeout을 3초로 계산할 수 있다.


ReadTimeout값 설정해보기

고려해야하는 3가지 시간
1. 요청을 처리하는데 소요되는 프로세싱 타임
2. 패킷 유실을 인지하고 재전송에 소요되는 시간 RTO
3. 패킷이 두 종단간을 흘러가는데 필요한 최소한의 물리적인 시간 RTO

(예시)
요청을 처리하는데 소요되는 시간 = 300ms
RTT 시간 = 10ms

-> 통신하기 위해 필요한 최소한의 시간은 310ms가 된다.

그러나! 데이터를 받는 과정 중에 한 번의 패킷 유실이 발생했다면?

-> 최소 RTO값을 적용했을 때 310ms로 처리할 수 있는 요청이 510ms가 소요되게 된다.

✅ 이러한 시간들은 적어도 1초를 넘기지 않을 것이기 때문에 ReadTimeout값을 1초로 설정할 수 있다.

☑️ 그러나 요청을 처리하는데 소요되는 프로세싱 타임이 1초가 넘어간다면 모든 요청에 대해 Read Timeout값이 1초가 넘어간다. 그래서 프로세싱 타임을 중요하게 고려!

✍🏻 마치며..

해당 내용은 나의 마지막 주간발표 내용이며,..
이때쯤 카테캠 멘토님이 카카오 서버에 restclient로 요청을 하는 부분에 Timeout 처리를 하라고 하셔서 알아보게 되었다. restclient와 restTemplate 서로 그리고 그 외에도 타임아웃 설정하는 부분이 다르니 자신이 사용하는 Spring의 http client에 맞게 잘 설정해보자!

레퍼런스
https://alden-kang.tistory.com/20

주간발표 ppt ㅎㅎ
https://www.figma.com/proto/24rfXtlwpKyh6l3UXcxvpI/Weekly-Presentation?node-id=297-2&node-type=frame&t=BhawDbMKyvxL8SZT-0&scaling=contain&content-scaling=fixed&page-id=0%3A1&starting-point-node-id=297%3A2&show-proto-sidebar=1

0개의 댓글