[英]Custom Retry strategy for Spring WebClient
I'm using a fixedRetry in order to repeat HTTP calls using WebClient.我正在使用 fixedRetry 以使用 WebClient 重复 HTTP 调用。 I want the first retry to be called after 5 minutes, the second one after 30 minutes, and the rest after 60 minutes.
我希望在 5 分钟后调用第一次重试,在 30 分钟后调用第二次,在 60 分钟后调用 rest。 Is there a way to do this using the fixedRetry?
有没有办法使用fixedRetry来做到这一点? I checked https://www.baeldung.com/spring-webflux-retry several times, but I haven't found a way to use 3 different values for the delay time.
我检查了https://www.baeldung.com/spring-webflux-retry几次,但我还没有找到一种方法来使用 3 个不同的延迟时间值。
This how the constructor looks like:这是构造函数的样子:
public MyService(WebClient client,
@Value("${retry.quantity}") int retries,
@Value("${retry.time.first}") int firstTime,
@Value("${retry.time.second}") int secondTime,
@Value("${retry.time.rest}") int restTime)
{
this.client = client;
this.fixedRetry = Retry.anyOf(ResponseException.class)
.fixedBackoff(Duration.ofSeconds(restTime))
.retryMax(retries)
.doOnRetry(exception ->
log.error("Exception on Retry is {} .", exception)
);
}
You would need to implement custom Retry
to achieve this.您需要实施自定义
Retry
来实现这一点。 Here is an example这是一个例子
private static class CustomRetrySpec extends Retry {
private final int retries;
private final Duration firstTime;
private final Duration secondTime;
private final Duration restTime;
public CustomRetrySpec(int retries, Duration firstTime, Duration secondTime, Duration restTime) {
this.retries = retries;
this.firstTime = firstTime;
this.secondTime = secondTime;
this.restTime = restTime;
}
@Override
public Publisher<?> generateCompanion(Flux<RetrySignal> retrySignals) {
return retrySignals.flatMap(this::getRetry);
}
private Mono<Long> getRetry(Retry.RetrySignal rs) {
if (rs.totalRetries() < retries) {
Duration delay;
if (rs.totalRetries() == 0) {
delay = firstTime;
} else if (rs.totalRetries() == 1) {
delay = secondTime;
} else {
delay = restTime;
}
log.debug("retry {} with backoff {}min", rs.totalRetries(), delay.toMinutes());
return Mono.delay(delay)
.thenReturn(rs.totalRetries());
} else {
log.debug("retries exhausted with error: {}", rs.failure().getMessage());
throw Exceptions.propagate(rs.failure());
}
}
}
Here is a test using StepVerifier.withVirtualTime
这是使用
StepVerifier.withVirtualTime
的测试
@Test
void testCustomRetrySpec() {
StepVerifier.withVirtualTime(() ->
process()
.retryWhen(new CustomRetrySpec(3,
Duration.ofMinutes(5),
Duration.ofMinutes(30),
Duration.ofMinutes(60))
)
)
.expectSubscription()
.expectNoEvent(Duration.ofMinutes(5))
.expectNoEvent(Duration.ofMinutes(30))
.expectNoEvent(Duration.ofMinutes(60))
.expectError()
.verify();
}
private Mono<?> process() {
return Mono.error(new RuntimeException("oops"));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.