在调用外部服务进行查询时,常常因为网络抖动、服务方限流等不可预知的一些因素造成查询失败。为了克服这些问题,引入了重试机制 Spring Retry.
以下 Demo 基于 SpringBoot 2.1.1
引入依赖
1 2 3 4 5
| <!-- https: <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> < /dependency>
|
Spring Retry 的 jar 包 pom 文件中已依赖 aspectj,这里无需引入。
添加 @EnableRetry 注解
在主类上加上 @EnableRetry
注解,表示启用重试机制
1 2 3 4 5 6 7 8
| @SpringBootApplication @EnableRetry public class LeafaceApplication {
public static void main(String[] args) { SpringApplication.run(LeafaceApplication.class, args); } }
|
编写测试案例
Controller 层
1 2 3 4 5 6 7 8 9 10 11 12
| @Controller @RequestMapping("/test") public class TestSpringRetryController {
@Autowired private TestRetryService retryService;
@RequestMapping("/retry") public void test(@RequestParam(required = false) Integer num) { retryService.testRetry(num); } }
|
service 层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Service @Slf4j public class TestRetryService {
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 3000, multiplier = 1.5)) public void testRetry(Integer num) { log.info("testRetry() ===>>> "); if (num < 0) { throw new RuntimeException("num < 0"); } }
@Recover public void testRecover() { log.info("testRecover() ===>>> "); }
}
|
执行测试
请求 http://localhost:8080/test/retry?num=-1
,控制台打印:
1 2 3 4
| 2021-09-11 17:45:11.877 INFO --- [nio-8080-exec-1] c.s.g.m.service.TestRetryService : testRetry() ===>>> 2021-09-11 17:45:14.884 INFO --- [nio-8080-exec-1] c.s.g.m.service.TestRetryService : testRetry() ===>>> 2021-09-11 17:45:19.389 INFO --- [nio-8080-exec-1] c.s.g.m.service.TestRetryService : testRetry() ===>>> 2021-09-11 17:45:19.390 INFO --- [nio-8080-exec-1] c.s.g.m.service.TestRetryService : testRecover() ===>>>
|
@Retryable 注解中的参数说明:
value:抛出指定异常才会重试
maxAttempts:最大重试次数,默认为3(包括第一次调用)
include:默认为空,当 exclude 也为空时,所有异常都重试
exclude:指定不处理的异常,默认空,当 include 也为空时,所有异常都重试
backoff:重试等待策略,默认使用 @Backoff
@Backoff 注解中的参数说明:
value 默认为 1000L
delay 表示重试的延迟时间,默认为 0L
multiplier 表示延迟倍数(上一次延时时间是这一次的倍数),默认为 0.0D