日常开发中经常会遇到接口调用失败的问题,尤其是两个系统对接时,当接口调用失败通常会使用一些方法来进行重试,比如for循环while等,但是这种方式代码入侵性比较大而且不变维护。
实际上spring已经实现了相关功能,通过@Retryable注解在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。
使用步骤
1、添加依赖
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency>
2、在启动类或者配置类或者需重试方法所在的类上添加注解@EnableRetry
启动类示例
@SpringBootApplication @EnableRetry public class DataTransferApplication { public static void main(String[] args) { SpringApplication.run(DataTransferApplication.class, args); } }
配置类示例
@EnableRetry @Configuration public class RetryConfig { }
3、在需要重试的方法上添加@Retryable注解
@Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5)) @Override public RetResult manualUploadTemporaryTask(ManualUploadTemporaryTaskReq req) { System.out.println("manualUploadTemporaryTask" + "********"); for (int i = 0 ; i < 5 ; i ++){ int a = 0 / i; } return RetResponse.makeOKRsp(); } @Recover public RetResult temporaryTaskRecover(Exception e,ManualUploadTemporaryTaskReq req){ System.out.println("异常信息是:" + e.getMessage()); System.out.println("=============" + req.toString()); return RetResponse.makeErrRsp("上传失败请稍后再试"); }
运行结果
参数说明,Retryable参数列表毕竟多选择几个常用的解释一下,具体可以看官网
interceptor:可以通过该参数,指定方法拦截器的bean名称
value:抛出指定异常才会重试
include:和value一样,默认为空,当exclude也为空时,默认所以异常
exclude:指定不处理的异常
maxAttempts:最大重试次数,默认3次
backoff:重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
@Recover说明
当重试耗尽时,用于@Retryable重试失败后处理方法,此方法里的异常一定要是@Retryable方法里抛出的异常,否则不会调用这个方法。
1、方法的返回值必须与@Retryable方法一致
2、方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要与@Retryable方法的参数一致
3、@Retryable方法和@Recover方法要在同一类中