본문 바로가기
프로그래밍/SpringBoot

WebClient - java.util.concurrent.TimeoutException

by JLearn 2026. 3. 28.
반응형

java.util.concurrent.TimeoutException 발생 시점

- HTTP 레벨 타임아웃은 responseTimeout() 또는 timeout() 메서드로 설정한 것입니다.

java.util.concurrent.TimeoutException은 WebClient의 .timeout() 메서드를 사용할 때 지정된 시간 내에 이벤트가 도착하지 않으면 발생합니다.
예를 들면 .timeout(Duration.ofSeconds(5)) 메서드는 연결 수립부터 응답 수신까지 전체 작업에 timeout을 적용하며, 5초 내에 응답이 없으면 TimeoutException이 발생합니다.


발생 시점

# WebClient의 timeout() 메서드 사용

javawebClient.get()
    .uri("https://slow-api.com/data")
    .retrieve()
    .bodyToFlux(String.class)
    .timeout(Duration.ofSeconds(5))  // ← 5초 설정
    .subscribe();

// 5초 내에 응답이 없으면
// → java.util.concurrent.TimeoutException 발생
2. Future.get()의 timeout 초과
javaExecutorService executorService = Executors.newSingleThreadExecutor();
Future<Integer> future = executorService.submit(() -> {
    // 오래 걸리는 작업...
    return 100;
});

try {
    // 3초 내에 완료되지 않으면
    Integer result = future.get(3, TimeUnit.SECONDS);
} catch (TimeoutException e) {
    // → java.util.concurrent.TimeoutException 발생
}

Netty 타임아웃과 차이점

요청 시작
  ↓
[CONNECT_TIMEOUT_MILLIS: 3초] 
  → io.netty.channel.ConnectTimeoutException
  ↓
[ReadTimeoutHandler: 10초]
  → io.netty.handler.timeout.ReadTimeoutException
  ↓
[timeout(): 15초] ← 전체 작업 제한
  → java.util.concurrent.TimeoutException


Catch 방법

javawebClient.get()
    .uri("https://...")
    .retrieve()
    .bodyToFlux(String.class)
    .timeout(Duration.ofSeconds(5))
    .onErrorResume(java.util.concurrent.TimeoutException.class, ex -> {
        logger.error("TimeoutException: {}", ex.getMessage());
        return Flux.empty();
    })
    .subscribe();

Netty VS concurrent TimeoutException

# Netty의 타임아웃

  • import io.netty.channel.ConnectTimeoutException;
  • import io.netty.handler.timeout.ReadTimeoutException;

# Java concurrent 타임아웃

  • import java.util.concurrent.TimeoutException;

모두 다른 예외입니다.


결론

java.util.concurrent.TimeoutException은 WebClient의 .timeout() 메서드로 설정한 시간 초과 시 발생합니다.
전체 작업(연결부터 응답까지)의 통합 타임아웃이며 Netty 레벨의 타임아웃보다 상위 레벨의 타임아웃입니다.

반응형

댓글