콘텐츠로 이동

2022 11 13

2022-11-13

WebClient 타임아웃

  • 참고: https://www.baeldung.com/spring-webflux-timeout
  • WebClient timeout
    • ChannelOption.CONNECT_TIMEOUT_MILLIS : 서버와 커넥션 맺는데 기다리는 시간 (client 레벨)
    • responseTimeout
      • 순수 http 요청/응답에 대한 timeout
    • readTimeoutHandler/writeTimeoutHandler
      • TCP 레벨에서 적용됨으로 TLS handshake 할 때에도 적용됨
      • 관련된 암호화로 인해 전형적인 HTTP 응답보다 오래 걸릴 수 있음
  • Response Timeout
    • 요청에 따른 응답이 올 때 까지 기다리는 시간
      HttpClient client = HttpClient.create()
          .responseTimeout(Duration.ofSeconds(1));
      
      WebClient webClient = WebClient.builder()
          .clientConnector(new ReactorClientHttpConnector(client))
          .build();
      
  • Connection Timeout

    • 클라이언트-서버 간 커넥션이 필수적으로 수립되어야 하는 기간
    • 다양한 채널 옵션으로 configuration 가능
      HttpClient client = HttpClient.create()
          .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);
      
    • 네티는 기본적으로 30초를 수립시간으로 설정
    • keep-alive 옵션으로 Connection Idle 검사
      HttpClient client = HttpClient.create()
          .option(ChannelOption.SO_KEEPALIVE, true)
          .option(EpollChannelOption.TCP_KEEPIDLE, 300);
      
    • 해당 시간에 given time 안에 못했으면 ConnectionTimeoutException 던져짐
  • Read and Write Timeout
    • 특정 시간동안 데이터가 읽어진 적/데이터가 써진 적이 없을 때
    • ReadTimeoutException, WriteTimeoutException 발생
  • SSL/TLS Timeout

    • SSL 커넥션 수립시 시간
      HttpClient.create()
              .secure(spec -> spec.sslContext(SslContextBuilder.forClient()))
              .defaultConfiguration(SslProvider.DefaultConfigurationType.TCP)
              .handshakeTimeout(Duration.ofSeconds(30))
              .closeNotifyFlushTimeout(Duration.ofSeconds(10))
              .closeNotifyReadTimeout(Duration.ofSeconds(10));
      
    • SslHandshakeTimeoutException 발
  • Request-Level Timeout
    • 앞선 설명은 HttpClient 자체를 수립할 때 timeout 논의였음
    • request 자체에서 global 세팅도 가능
    • Reactive Timeout
      • 5초 안에 응답이 없다면, TimeoutException 발생함
        webClient.get()
                 .uri("https://url")
                 .retrieve()
                 .bodyToFlux(JsonDto.class)
                 .timeout(Duration.ofSeconds(5));