애플리케이션에서 외부 API 호출이나 DB 연결 시 간헐적으로 발생하는 Timeout 예외, 다들 한 번쯤은 겪어봤을 것이다. 그런데 정확히 어떤 타임아웃이 어디서 발생한 건지 헷갈릴 때가 많다. 이 글에서는 자주 혼동되는 세 가지 타임아웃:
을 개념부터 실제 적용 사례까지 한 번에 정리한다.
서버에 연결을 시도할 때까지 기다리는 최대 시간이다. 흔히 TCP 3-way-handshake가 이루어지는 시점에서 서버가 응답하지 않으면 발생한다.
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(5)) // 연결 시도 제한 5초
.build();
서버와 연결은 되었지만, 데이터 수신이 일정 시간 내에 일어나지 않을 때 발생하는 타임아웃이다. 주로 다음 응답 패킷이 오지 않아서 연결이 끊기는 상황이다.
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(5000); // 5초
factory.setReadTimeout(3000); // 3초
☝️ 이때의 Read Timeout은 Socket Timeout과 거의 같은 의미로 사용된다.
서버와 연결이 이미 수립된 상태에서, 특정 I/O 작업(예: InputStream.read())이 지정된 시간 내에 완료되지 않으면 발생하는 타임아웃이다.
일부 프레임워크에서는 Socket Timeout과 Read Timeout을 구분하지 않고 동일하게 쓰기도 한다.
// Express.js 예제
app.get('/slow', (req, res) => {
setTimeout(() => res.send('응답 지연 완료'), 10000); // 10초 딜레이
});
curl --max-time 3 http://localhost:3000/slow
| 항목 | 의미 | 주로 발생하는 위치 |
|---|---|---|
| Connection Timeout | 연결 수립 전, 서버 응답 기다리는 최대 시간 | TCP 3-way-handshake |
| Socket Timeout | 연결 후, 응답 패킷이 지연되면 발생 | 패킷 수신/전송 중 |
| Read Timeout | 연결 후, I/O 작업 지연 시 발생 | InputStream.read(), DB 쿼리 등 |
Connection, Read, Socket Timeout은 이름은 비슷하지만 각각 다른 네트워크 단계에서 발생한다. 서비스 장애 예방과 빠른 에러 대응을 위해 명확한 구분과 적절한 설정이 필수다.
실전에서는 "Connection이 안 돼요" 같은 말보다 정확히 어떤 Timeout인지 로그로 구분하고, 그에 맞는 트러블슈팅을 해보자