强制: 统一采用
Spring-Retry
库来完成重试操作,不得 通过循环等方式来自实现
方案有如下两种(推荐采用注解方式,特殊场景可以通过 RetryTemplate
自行定制):
注解式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
424j
public class RetryCallService {
// 最大重试次数
private static final int MAX_ATTEMPTS = 10;
// 延迟策略
private static final long DELAY = 1000 * 2L;
private static final long MAX_DELAY = DELAY * 60;
private int count = 0;
private long start = 0;
.class}, (value = {BizException
maxAttempts = MAX_ATTEMPTS,
backoff = 2)) (delay = DELAY, maxDelay = MAX_DELAY, multiplier =
public Boolean retry() throws Exception {
if (start == 0) {
start = System.currentTimeMillis();
}
doSomething();
return true;
}
// 达到最大重试次数后的补偿方案
public Boolean recover(BizException e) {
log.info("达到最大尝试次数,执行最后的补偿操作,异常信息为:{}", e.getMessage());
return false;
}
// 具体的业务逻辑
private void doSomething() throws Exception {
count++;
log.info("进行第 {} 次尝试,当前时间过去了:{} 秒", count, (System.currentTimeMillis() - start) / 1000);
throw new BizException("模拟业务异常");
}
}
模板模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
624j
public class RetryCallServiceTwo {
// 最大重试次数
private static final int MAX_ATTEMPTS = 10;
// 延迟策略
private static final long INITIAL_INTERVAL = TimeUnit.SECONDS.toMillis(2);
private static final long MAX_INTERVAL = TimeUnit.MINUTES.toMillis(5);
private int count = 0;
private long start = 0;
private RetryTemplate retryTemplate;
// 初始化重试模板
public void initRetryTemplate() {
retryTemplate = new RetryTemplate();
ExponentialBackOffPolicy retryPolicy = new ExponentialBackOffPolicy();
retryPolicy.setInitialInterval(INITIAL_INTERVAL);
retryPolicy.setMaxInterval(MAX_INTERVAL);
retryPolicy.setMultiplier(2);
retryTemplate.setRetryPolicy(new SimpleRetryPolicy(MAX_ATTEMPTS));
retryTemplate.setBackOffPolicy(retryPolicy);
}
public Boolean retry() throws Exception {
// 典型的 Spring Template 用法
retryTemplate.execute(new RetryCallback<Boolean, Exception>() {
public Boolean doWithRetry(RetryContext context) throws Exception {
doSomething();
return null;
}
}, new RecoveryCallback<Boolean>() {
public Boolean recover(RetryContext context) {
return RetryCallServiceTwo.this.recover(context);
}
});
return true;
}
// 达到最大重试次数后的补偿方案
public Boolean recover(RetryContext retryContext) {
log.info("达到最大尝试次数,执行最后的补偿操作,异常信息为:{}", retryContext.getLastThrowable().getMessage());
return false;
}
private void doSomething() {
if(start == 0) {
start = System.currentTimeMillis();
}
count++;
log.info("进行第 {} 次尝试,当前时间过去了:{} 秒", count, (System.currentTimeMillis() - start) / 1000);
throw new BizException("模拟业务异常");
}
}