mun*_*nky 1 java spring webclient spring-boot
我使用Spring-boot-3 @GetExchangea WebClient,有时会遇到以下错误:
java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS
Run Code Online (Sandbox Code Playgroud)
如果使用来@GetExchange指示WebClient重试,最佳实践是什么?这个新注释没有足够的文档。
您需要使用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());
}
Run Code Online (Sandbox Code Playgroud)
[编辑]对于您遇到的特殊情况,即异常
java.lang.IllegalStateException: Timeout on blocking read for 5000000000 NANOSECONDS
Run Code Online (Sandbox Code Playgroud)
可能的原因是您的服务正在等待请求的答复,5 秒后(默认情况下),服务挂起。
有必要增加所使用的 http 客户端的读取超时。我已相应地编辑了代码,并在相关行上添加了注释。
| 归档时间: |
|
| 查看次数: |
996 次 |
| 最近记录: |