Timeout은 네트워크 통신에서 클라이언트와 서버 간 특정 작업이 완료되기까지 기다리는 최대 시간을 정의하는 설정이다. Timeout 설정은 네트워크 환경과 서비스 성격에 따라 적절히 조정해야 한다. 이 글에서는 Connection Timeout, Socket Timeout, Read Timeout의 차이를 정리했다.
Connection Timeout은 클라이언트가 서버에 TCP 연결을 맺는 과정에서 일정 시간 내 연결이 성립되지 않으면 발생하는 시간 초과이다. 클라이언트는 서버와 통신을 하기 위해 TCP 3-way Handshake 과정을 거치는데, TCP 3-way Handshake 과정 중 SYN-ACK 패킷을 주고받는 데 걸리는 시간이 Connection Timeout으로 설정된다. db에 연결 실패, 초기 연결 실패가 이에 해당된다.
해외 서버와 통신하는 경우처럼 네트워크 연결이 불안정한 경우 Timeout을 넉넉히 설정해야 한다.
3-way Handshake을 통해 Connection이 맺어진 후, 서버는 데이터를 여러 패킷으로 나누어 전송한다. 각 패킷 간 전송 간격(Gap)이 설정된 임계치를 초과하면 Socket Timeout이 발생한다.

즉, Socket Timeout은 TCP Connection 상태에서, 클라이언트에서 서버로 데이터를 전송하는 동안 발생하는 시간 초과이다. 데이터 쓰기에 실패하는 경우도 이에 해당한다.
특히 대용량 파일을 전송하거나, 장시간 데이터 전송이 필요한 파일 업로드, 스트리밍 서비스의 경우는 전송 시간이 오래 걸리기 때문에 데이터 전송 속도가 느리더라도 연결을 유지할 수 있도록 Timeout을 적당히 길게 설정해야 한다.
Read Timeout은 클라이언트가 요청을 보낸 후 서버로부터 응답을 기다리는 시간이 초과될 때 상황이다. 클라이언트의 요청은 정상적으로 전송되었지만 서버가 과부하 상태일 때 발생할 수 있다. 이때, 데이터 수신이 시작되지 않으면 Read Timeout이 발생한다.
Read Timeout은 클라이언트가 무작정 대기하는 상황이 발생할 수 있기 때문에 UX를 고려하여 클라이언트에게 적절한 응답 혹은 에러를 반환해야 한다.
서버 측에서는 재시도 로직을 구현하여 Timeout 문제를 해결할 수 있다.
나의 경우도 Spring Retry를 사용하여 Spring Boot에서 FastAPI로 요청을 보낼 때 발생한 Read Timeout 문제를 해결한 경험이 있다.
Spring WAS -> FastAPI WAS -> OpenAI 당시 구현은 @Retryable 어노테이션을 사용하여 요청 실패 시 자동 재시도를 설정하고, maxAttempts와 backoff 속성을 통해 최대 재시도 횟수와 대기 시간을 조정했다. 이를 통해 이전에 두 줄 이상의 데이터를 요청하면 발생하던 Timeout 문제를 네 줄까지 성공적으로 해결할 수 있었다. 네 줄 이상은 테스트 해보지 않았다.
일반적으로 재요청이 성공하는 이유는 요청 실패 원인이 일시적인 네트워크 지연, 서버 부하, 또는 세션 타임아웃과 같은 가변적 요소이기 때문이다. 재요청 시 이러한 일시적 문제가 해소될 가능성이 높다.
나같은 경우, 로컬에서 테스트했기 때문에 캐싱이나 인프라 기능과는 무관했다. 순수하게 네트워크 통신과 서버 처리의 시간적 특성 때문이라고 판단했다. 앞서 말했듯, 네트워크 혼잡이나 서버 과부하로 인한 일시적 문제가 재시도를 통해 해소되었을 가능성이 높다.
일시적 지연 해소: 네트워크 혼잡이나 서버 과부하로 인한 일시적 문제는 시간이 지나면서 해소될 가능성이 높음. Spring Retry는 재시도를 통해 이러한 문제가 해결된 시점에 요청을 성공시킴.
Exponential Backoff로 부하 완화: Backoff는 재시도 간 대기 시간을 점진적으로 늘려 서버와 네트워크에 안정화 시간을 제공. OpenAI API의 처리량 제한(rate limit)이 해소된 시점에 재시도가 성공할 가능성이 높아짐.
Stateless Retry로 독립적 요청 처리: 각 재시도가 독립적인 시도로 간주되어, 이전 요청과 다른 네트워크 경로나 서버 리소스를 활용할 수 있음.
Spring Retry는 동일한 요청을 다시 생성하여 서버에 요청하는 것이다. 때문에 자칫하면 서버에 부하를 줄 수 있다. 이때,
전략을 사용하여 서버 부하를 줄일 수 있다.
추가로 리트라이 실패 시 로그 기록 및 관리자 알림 설정하여 로깅 및 모니터링할 수 있다.
Connection Timeout, Socket Timeout, Read Timeout은 네트워크 연결 및 데이터 송수신 과정에서 중요한 설정 값이다. 각 Timeout은 서비스 특성과 사용 사례에 따라 적절히 설정해야 하며, 예를 들어, API 기반 서비스는 짧은 Read Timeout을 설정해 신속한 실패 처리를 유도하는 반면, 스트리밍 서비스는 데이터 전송이 지속적으로 이루어져야 하므로 더 긴 Socket Timeout을 설정하는 것이 적절하다.