如何解决Spring webclient - 每次重试后增加超时持续时间
我正在寻找一种方法来增加网络客户端调用连续重试后超时的持续时间。
例如,我希望第一个请求在 50 毫秒后超时,第一次重试将在 500 毫秒后超时,第二次也是最后一次重试的超时持续时间为 5000 毫秒。
我不知道该怎么做。我只知道如何将超时值设置为所有重试的固定持续时间。
例如
public Flux<Employee> findAll()
{
return webClient.get()
.uri("/employees")
.retrieve()
.bodyToFlux(Employee.class)
.timeout(Duration.ofMillis(50))
.retry(2);
}
解决方法
您可以将退避和超时逻辑抽象为一个单独的实用程序函数,然后只需在发布商上调用 transform()
。
在您的情况下,您似乎在追求基本的退避功能 - 取一个初始超时值,然后将其乘以一个因子,直到达到最大值。我们可以这样实现:
public <T> Flux<T> retryWithBackoffTimeout(Flux<T> flux,Duration timeout,Duration maxTimeout,int factor) {
return mono.timeout(timeout)
.onErrorResume(e -> timeout.multipliedBy(factor).compareTo(maxTimeout) < 1,e -> retryWithBackoffTimeout(mono,timeout.multipliedBy(factor),maxTimeout,factor));
}
...但这当然可以是您喜欢的任何类型的超时逻辑。
使用该实用程序函数后,您的 findAll()
方法变为:
public Flux<Employee> findAll()
{
return webClient.get()
.uri("/employees")
.retrieve()
.bodyToFlux(Employee.class)
.transform(m -> retryWithBackoffTimeout(m,Duration.ofMillis(50),Duration.ofMillis(500),10));
}
,
您是否探索过@Retryable?如果没有,那么这里是选项。添加这个依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
注释你的主类
@EnableRetry
public class MainClass{
...
}
然后注释您调用调用的事务
public interface BackendAdapter {
@Retryable(
value = {YourCustomException.class},maxAttempts = 4,backoff = @Backoff(random = true,delay = 1000,maxDelay = 5000,multiplier = 2)
)
public String getBackendResponse(boolean simulateretry,boolean simulateretryfallback);
}
如果您将延迟设置为 1000 毫秒,将 maxDelay 设置为 5000 毫秒并将乘数设置为 2,则重试时间将类似于以下 4 次尝试:
Retry 1 — 1605
Retry 2 — 2760
Retry 3 — 7968
Retry 4 — 14996
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。