java Spring RestTemplate:指数退避重试策略
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31906419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring RestTemplate: Exponential Backoff retry policy
提问by Simon
I'm reading up on GCM: https://developers.google.com/cloud-messaging/server
我正在阅读 GCM:https: //developers.google.com/cloud-messaging/server
and one of the requirements is that the server needs to be able to:
其中一项要求是服务器需要能够:
- handle requests and resend them using exponential back-off.
- 处理请求并使用指数退避重新发送它们。
I use Spring RestTemplate for my backend which comes from Spring Boot. There doesn't seem to be a method which I can use to set my retry policy in the docs: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
我使用 Spring RestTemplate 作为我的后端,它来自 Spring Boot。似乎没有一种方法可以用来在文档中设置我的重试策略:http: //docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/ RestTemplate.html
Also when I googled, I found the RetryTemplate, but it is part of Spring Batch and doesn't extend RestTemplate which makes me think that it is not supposed to be used for Rest operations, but rather Spring Batch operations like processing large amount of transactions: http://docs.spring.io/spring-batch/2.1.x/apidocs/org/springframework/batch/retry/support/RetryTemplate.html
另外,当我用谷歌搜索时,我找到了 RetryTemplate,但它是 Spring Batch 的一部分并且没有扩展 RestTemplate 这让我认为它不应该用于 Rest 操作,而是 Spring Batch 操作,例如处理大量事务:http: //docs.spring.io/spring-batch/2.1.x/apidocs/org/springframework/batch/retry/support/RetryTemplate.html
Is there a way I can use exponential backoff with Spring RestTemplate?
有没有办法可以在 Spring RestTemplate 中使用指数退避?
回答by Konstantin Konyshev
Good day!
再会!
I guess, desired behavior could be achived by implementing custom Sleeperclass.
我想,可以通过实现自定义Sleeper类来实现所需的行为。
Next you need to set this sleeper to BackOffPolicyas follows:
接下来,您需要将这个 sleeper 设置为BackOffPolicy,如下所示:
public class RetryTest {
public static final Logger LOG = LoggerFactory.getLogger(RetryTemplate.class);
@org.junit.Test
public void testRT() {
RetryTemplate retryTemplate = new RetryTemplate();
final SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(5);
retryTemplate.setRetryPolicy(retryPolicy);
Sleeper sleeper = new Sleeper() {
private long timeToSleep = 0;
@Override
public void sleep(long timeout) throws InterruptedException {
if (timeToSleep ==0) {
timeToSleep = timeout;
} else {
timeToSleep = (long) (timeToSleep * Math.E);
}
LOG.warn("sleeping for: {}", timeToSleep);
Thread.sleep(timeToSleep);
}
};
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy().withSleeper(sleeper);
retryTemplate.setBackOffPolicy(backOffPolicy);
retryTemplate.execute(new RetryCallback<Void, ResourceAccessException>() {
@Override
public Void doWithRetry(RetryContext retryContext) throws ResourceAccessException {
LOG.debug(">RetryCount: {}", retryContext.getRetryCount());
new RestTemplate().getForObject("https://unreachable.host", String.class);
return null;
}
});
}
}
Also there is ExponentialBackOffPolicyby spring-retry.
spring-retry还有ExponentialBackOffPolicy。
Hope this would help.
希望这会有所帮助。
回答by Vikesh Royal
You can use like the below code .
您可以像下面的代码一样使用。
@Retryable(exceptionExpression="#{@exceptionChecker.shouldRetry(#root)}",
maxAttemptsExpression = "#{@integerFiveBean}",
backoff = @Backoff(delayExpression = "#{1}",
maxDelayExpression = "#{5}", multiplierExpression = "#{1.1}"))
public void service3() {
...
}