java 重试Spring @HttpExchange

5vf7fwbs  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(317)

我正在使用SpringBoot 3 @GetExchangeWebClient,有时我们会遇到
java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS
在@GetExchange的情况下,指示WebClient重试的最佳实践是什么?关于这个新注解的文档还不多。
太感谢你了,
安德里亚

czfnxgou

czfnxgou1#

您需要使用ExchangeFilterFunctions来帮助您定义重试逻辑。

@Bean
    FooClient fooClient() {
        WebClient webClient =WebClient.builder()
            .baseUrl("your_base_url")
            .filter(withRetryableRequests())
            .build();
        HttpServiceProxyFactory factory=HttpServiceProxyFactory
            .builder(WebClientAdapter.forClient(webClient))
            .blockTimeout(Duration.of(HTTP_CLIENT_READ_TIMEOUT, ChronoUnit.SECONDS)) // Configure how long to wait for a response for an HTTP service method with a synchronous (blocking) method signature.By default this is 5 seconds.
            .build();
        return factory.createClient(FooClient.class);
    }

  
    private ExchangeFilterFunction withRetryableRequests() {
        return (request, next) -> next.exchange(request)
                .flatMap(clientResponse -> Mono.just(clientResponse)
                        .filter(response ->  clientResponse.statusCode().isError())
                        .flatMap(response -> clientResponse.createException())
                        .flatMap(Mono::error)
                        .thenReturn(clientResponse))
                .retryWhen(this.retryBackoffSpec());
    }
    
    private RetryBackoffSpec retryBackoffSpec() {
        return Retry.backoff(3, Duration.ofSeconds(2))
                .filter(throwable->throwable instanceof  WebClientResponseException) // here filter on the errors for which you want a retry
                .doBeforeRetry(retrySignal -> log.warn("Retrying request after following exception : {}",  retrySignal.failure().getLocalizedMessage()))
                .onRetryExhaustedThrow((retryBackoffSpec, retrySignal)  -> retrySignal.failure());
    }

**[编辑]**针对您遇到的特定情况,即异常

java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS

可能的原因是您的服务正在等待对请求的应答,并且在5秒后(默认情况下),服务挂起。
有必要增加所使用的http客户端的读取超时。我已经相应地编辑了代码,并在相关行上添加了注解。

相关问题