由于网络不稳定或网络抖动经常会造成接口请求失败的情况,当我们再去尝试就成功了,这就是重试机制。
本文首发于Java潘老师个人博客:SpringBoot整合spring-retry组件实现重试机制
其主要目的就是要尽可能地提高请求成功的概率,但一般情况下,我们请求第一次失败,代码运行就抛出异常结束了,如果想再次请求可能还需要手工操作,这非常地不方便,可行性也不佳。因此,Spring框架提供了对重试机制支持,并且在Spring Cloud中可以与Hystrix结合使用,可以避免访问到已经不正常的实例。
重试机制要素如下:
对于非幂等性的方法我们要慎用重试机制,可能会造成意料之外的后果。
所谓幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
下面我们就来看下,我们应该如何使用SpringBoot来整合spring-retry组件实现重试机制。
首先我们在SpringBoot项目中的pom.xml
添加相关依赖,如下:
<!-- 重试相关依赖包 --> <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.2.4.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency>
在主启动类Application上添加@EnableRetry注解,实现对重试机制的支持
@SpringBootApplication @EnableRetry public class RetryApplication { public static void main(String[] args) { SpringApplication.run(RetryApplication.class, args); } }
注意:@EnableRetry也可以使用在配置类、ServiceImpl类、方法上
我们针对需要实现重试的方法上添加@Retryable
注解,使该方法可以实现重试,这里我列出ServiceImpl中的一个方法:
@Service public class RetryServiceImpl implements RetryService { @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5)) public String testRetry() throws Exception { System.out.println("开始执行代码:"+ LocalTime.now()); int code = 0; // 模拟一直失败 if(code == 0){ // 这里可以使自定义异常,@Retryable中value需与其一致 throw new Exception("代码执行异常"); } System.out.println("代码执行成功"); return "success"; } }
说明:@Retryable配置元数据情况:
value :针对指定抛出的异常类型,进行重试,这里指定的是Exception
maxAttempts :配置最大重试次数,这里配置为3次(包含第一次和最后一次)
delay: 第一次重试延迟间隔,这里配置的是2s
multiplier :每次重试时间间隔是前一次几倍,这里是1.5倍
@RestController @RequestMapping("/test") public class TestController { @Autowired private RetryService retryService; @GetMapping("/retry") public String testRetry() throws Exception { return retryService.testRetry(); } }
发送请求后,我们发现后台打印情况,确实重试了3次,并且在最后一次重试失败的情况下,才抛出异常,具体如下(可以注意下时间间隔):
一般情况下,我们重试最大设置的次数后,仍然失败抛出异常,我们会通过全局异常处理类进行统一处理,但是我们其实也可以自行处理,可以通过@Recover
注解来实现,具体如下:
@Service public class RetryServiceImpl implements RetryService { @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5)) public String testRetry() throws Exception { System.out.println("开始执行代码:"+ LocalTime.now()); int code = 0; if(code == 0){ // 这里可以使自定义异常,@Retryable中value需与其一致 throw new Exception("代码执行异常"); } System.out.println("代码执行成功"); return "success"; } /** * 最终重试失败处理 * @param e * @return */ @Recover public String recover(Exception e){ System.out.println("代码执行重试后依旧失败"); return "fail"; } }
注意:
1)@Recover的方法中的参数异常类型需要与重试方法中一致
2)该方法的返回值类型与重试方法保持一致
再次测试如下(发现不会再抛出异常):
本文首发于Java潘老师个人博客:SpringBoot整合spring-retry组件实现重试机制
这一次的节点更新覆盖了美国、欧洲、新加坡、日本、韩国、香港、加拿大等地区,最高速度可达20.1 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
这一次的节点更新覆盖了香港、韩国、美国、新加坡、日本、加拿大、欧洲等地区,最高速度可达22.8 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
摘要: 本篇文章给大家谈谈动物医院名字大全集图片,以及动物医院牌匾对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、请帮忙起个宠物医院的名字... 本篇
摘要: 今天给各位分享宠物品牌起名字大全的知识,其中也会对宠物品牌介绍进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、宠物店取什么名字好...
这一次的节点更新覆盖了新加坡、香港、日本、欧洲、加拿大、韩国、美国等地区,最高速度可达21 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
这一次的节点更新覆盖了加拿大、香港、美国、新加坡、韩国、日本、欧洲等地区,最高速度可达20 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
摘要: 今天给各位分享北京宠物医院前十名一朝阳区宠爱医院的知识,其中也会对北京朝阳区宠物医院哪个好进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!本文目录一览:1、.
这一次的节点更新覆盖了日本、欧洲、韩国、香港、美国、新加坡、加拿大等地区,最高速度可达18.1 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
摘要: 本篇文章给大家谈谈动物防疫计划书怎么写,以及动物防疫计划的编制对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、动物防疫工作个人总结报告...
这一次的节点更新覆盖了新加坡、香港、美国、欧洲、加拿大、日本、韩国等地区,最高速度可达20.6 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。