Spring 如果未设置 maxDelay,则 retryTemplate 会过早触发
Spring retryTemplate fires too early if no maxDelay is set
我希望我的 RetryTemplate 有 300000 毫秒的延迟 - 5 分钟乘以每次尝试 1.1。但是,它只会将下一次尝试延迟 30 秒。这是一个简化的例子:
@Service
public class Foo {
private static final Logger log = Logger.getLogger(Foo.class);
@Retryable(value = Exception.class,
backoff = @Backoff(delay = 300000, multiplier = 1.1))
public void run() throws Exception {
new Bar().run();
}
@Recover
void recover(Exception e) {
log.error("e", e);
}
}
public class Bar {
private static final Logger log = Logger.getLogger(Bar.class);
public void run() throws Exception{
log.info("hier");
throw new Exception();
}
}
@Bean
CommandLineRunner runner() {
return (String[] a) -> {
scheduler.schedule(() -> {
try {
retryTemplate.execute(arg -> {
foo.run();
return null;
});
} catch (Exception e) {
}
}, 1 , TimeUnit.SECONDS);
};
}
日志是在这些时间制作的:
2017-03-17 13:25:08.439 INFO 6500 --- [
2017-03-17 13:25:38.439 INFO 6500 --- [
2017-03-17 13:26:08.440 INFO 6500 --- [
2017-03-17 13:26:08.444 ERROR 6500 --- [
无论我是否使用调度程序(因为原始代码需要初始延迟,所以存在调度程序)都没有什么区别。)
现在,如果我将 maxDelay 添加到 @Backoff
@Backoff(delay = 300000, multiplier = 1.1, maxDelay = 1000000000)
它完全按预期工作 - 5 分钟后触发,然后是 5*1.1 分钟等。然而,阅读@Backoff - maxDelay 的 javadoc,它说它默认为 0,如果小于 delay
则被忽略
/**
* The maximimum wait (in milliseconds) between retries. If less than the
* {@link #delay()} then ignored.
*
* @return the maximum delay between retries (default 0 = ignored)
*/
long maxDelay() default 0;
有什么我不明白的吗?似乎 maxDelay 默认为 30 秒,这与 javadoc 解释的完全不同。
使用spring-重试版本为1.1.3
这是 javadoc 中的错误 - 请参阅代码 here。
policy.setMaxInterval(max > min ? max : ExponentialBackOffPolicy.DEFAULT_MAX_INTERVAL);
和
public static final long DEFAULT_MAX_INTERVAL = 30000L;
我希望我的 RetryTemplate 有 300000 毫秒的延迟 - 5 分钟乘以每次尝试 1.1。但是,它只会将下一次尝试延迟 30 秒。这是一个简化的例子:
@Service
public class Foo {
private static final Logger log = Logger.getLogger(Foo.class);
@Retryable(value = Exception.class,
backoff = @Backoff(delay = 300000, multiplier = 1.1))
public void run() throws Exception {
new Bar().run();
}
@Recover
void recover(Exception e) {
log.error("e", e);
}
}
public class Bar {
private static final Logger log = Logger.getLogger(Bar.class);
public void run() throws Exception{
log.info("hier");
throw new Exception();
}
}
@Bean
CommandLineRunner runner() {
return (String[] a) -> {
scheduler.schedule(() -> {
try {
retryTemplate.execute(arg -> {
foo.run();
return null;
});
} catch (Exception e) {
}
}, 1 , TimeUnit.SECONDS);
};
}
日志是在这些时间制作的:
2017-03-17 13:25:08.439 INFO 6500 --- [
2017-03-17 13:25:38.439 INFO 6500 --- [
2017-03-17 13:26:08.440 INFO 6500 --- [
2017-03-17 13:26:08.444 ERROR 6500 --- [
无论我是否使用调度程序(因为原始代码需要初始延迟,所以存在调度程序)都没有什么区别。)
现在,如果我将 maxDelay 添加到 @Backoff
@Backoff(delay = 300000, multiplier = 1.1, maxDelay = 1000000000)
它完全按预期工作 - 5 分钟后触发,然后是 5*1.1 分钟等。然而,阅读@Backoff - maxDelay 的 javadoc,它说它默认为 0,如果小于 delay
则被忽略/**
* The maximimum wait (in milliseconds) between retries. If less than the
* {@link #delay()} then ignored.
*
* @return the maximum delay between retries (default 0 = ignored)
*/
long maxDelay() default 0;
有什么我不明白的吗?似乎 maxDelay 默认为 30 秒,这与 javadoc 解释的完全不同。
使用spring-重试版本为1.1.3
这是 javadoc 中的错误 - 请参阅代码 here。
policy.setMaxInterval(max > min ? max : ExponentialBackOffPolicy.DEFAULT_MAX_INTERVAL);
和
public static final long DEFAULT_MAX_INTERVAL = 30000L;