我想在响应为5xx时等待10秒后重试请求3次。但我看不到可以使用的方法。在物体上
WebClient.builder()
.baseUrl("...").build().post()
.retrieve().bodyToMono(...)
我可以看到方法:
在具有重试次数但没有延迟的条件下重试
.retry(3, {it is WebClientResponseException && it.statusCode.is5xxServerError} )
重试,有退避次数和次数,但无条件
.retryBackoff
还有一个retryWhen
,但我不确定如何使用
答案 0 :(得分:2)
您可以采用以下方法进行操作:
exchange()
方法获取无异常的响应,然后在5xx响应上抛出特定的(自定义)异常(这与retrieve()
始终会抛出WebClientResponseException
的异常)不同状态为4xx
或5xx
)reactor-extra
-它包含了一种使用retryWhen()
进行更复杂和特定重试的好方法。然后,您可以指定随机退避重试,该重试重试在10秒后开始,直到任意时间,最多尝试3次。 (或者,您当然可以使用other available methods选择其他策略。)例如:
//...webclient
.exchange()
.flatMap(clientResponse -> {
if (clientResponse.statusCode().is5xxServerError()) {
return Mono.error(new ServerErrorException());
} else {
//Any further processing
}
}).retryWhen(
Retry.anyOf(ServerErrorException.class)
.randomBackoff(Duration.ofSeconds(10), Duration.ofHours(1))
.maxRetries(3)
)
);
答案 1 :(得分:1)
使用extra-reacter,您可以像这样操作
:.retryWhen(Retry.onlyIf(this::is5xxServerError)
.fixedBackoff(Duration.ofSeconds(10))
.retryMax(3))
private boolean is5xxServerError(RetryContext<Object> retryContext) {
return retryContext.exception() instanceof WebClientResponseException &&
((WebClientResponseException) retryContext.exception()).getStatusCode().is5xxServerError();
}
答案 2 :(得分:1)
// ...
.retryWhen(
backoff(maxAttempts, minBackoff)
.filter(throwable -> ((WebClientResponseException) throwable).getStatusCode().is5xxServerError()))
// ...
答案 3 :(得分:0)
不推荐使用retryWhen和Retry.anyOf和Retry.onlyIf。我发现这种方法很有用,它使我们能够处理和引发用户定义的异常。
例如:
retryWhen(Retry.backoff(3, Duration.of(2, ChronoUnit.SECONDS))
.filter(error -> error instanceof UserDefinedException/AnyOtherException)
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) ->
new UserDefinedException(retrySignal.failure().getMessage())))