SpringBoot进阶教程(八十四)spring-retry

打印 上一主题 下一主题

主题 887|帖子 887|积分 2661

在日常的一些场景中, 很多需要进行重试的操作.而spring-retry是spring提供的一个基于spring的重试框架,某些场景需要对一些非常情况下的方法进行重试就会用到spring-retry。spring-retry可以资助我们以标准方式处理任何特定操作的重试。在spring-retry中,所有设置都是基于简单注释的。
v添加引用
  1.         <dependency>
  2.             <groupId>org.springframework.retry</groupId>
  3.             <artifactId>spring-retry</artifactId>
  4.         </dependency>
  5.         <dependency>
  6.             <groupId>org.springframework.boot</groupId>
  7.             <artifactId>spring-boot-starter-aop</artifactId>
  8.         </dependency>
复制代码
v启用@Retryable
  1. @SpringBootApplication
  2. @EnableRetry
  3. public class TestApplication {
  4.     public static void main(String[] args) {
  5.         SpringApplication.run(TestApplication.class, args);
  6.     }
  7. }
复制代码
要使用@EnabelRetry开启重试才行,声明在设置类或者启动类上都可以激活。
v在方法上添加@Retryable

创建service接口
  1. public interface HomeService {
  2.     int convertStatus(int status) throws Exception;
  3. }
复制代码
在service实现类并添加@Retryable
  1. @Slf4j
  2. @Service
  3. public class HomeServiceImpl implements HomeService {
  4.     /**
  5.      * value:抛出指定异常才会重试
  6.      * include:和value一样,默认为空,当exclude也为空时,默认所有异常
  7.      * exclude:指定不处理的异常
  8.      * maxAttempts:最大重试次数,默认3次(包括第一次调用)
  9.      * backoff:重试等待策略,
  10.      * 默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000; 以毫秒为单位的延迟(默认 1000);delay:重试的间隔时间,就是value
  11.      * multiplier delay时间的间隔倍数,默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
  12.      * @param status
  13.      * @return
  14.      * @throws Exception
  15.      */
  16.     @Override
  17.     @Retryable(retryFor = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
  18.     public int convertStatus(int status) throws Exception{
  19.         System.out.println("进入convertStatus时间:"+ LocalTime.now());
  20.         if (status < 0){
  21.             throw new Exception("状态小于0是非法的");
  22.         }
  23.         System.out.println("convertStatus: status++");
  24.         return status++;
  25.     }
  26.     /**
  27.      * Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法。
  28.      * 如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。
  29.      * @Recover标记方法必须要与@Retryable注解的方法“形参”保持一致,第一入参为要重试的异常(一定要是@Retryable方法里抛出的异常或者异常父类),其他参数与@Retryable保持一致,返回值也要一样,否则无法执行!
  30.      *
  31.      * @param e
  32.      * @param status @Retryable注解的原方法参数,可以保留,也可以不要。
  33.      * @return
  34.      */
  35.     @Recover
  36.     public int recover(Exception e, int status) {
  37.         //记日志到数据库 或者调用其余的方法
  38.         System.out.println(String.format("兜底方法执行,异常信息:%s,status:%d", e.toString(), status));
  39.         return -1;
  40.     }
  41. }
复制代码
@Retryable修饰的convertStatus()方法,如果调用期间报了非常,那么它将进行重试3次(默认三次),如果超过最大重试次数,则执行@Retryable修饰的recover()方法,
创建controller
  1. @Slf4j
  2. @RestController
  3. public class HomeController {
  4.     @Autowired
  5.     HomeService homeService;
  6.     @GetMapping("convertStatus")
  7.     public ReturnValue<?> convertStatus(@RequestParam("token") String token,
  8.                                         @RequestParam("status") int status) throws Exception {
  9.         int result = homeService.convertStatus(status);
  10.         return ReturnValue.buildSuccessResult(result);
  11.     }
  12. }
复制代码
验证效果

v常用注解介绍

@EnableRetry启用重试,开启aop的功能,默认使用jdk的动态代理。proxyTargetClass属性为true时(默认false),使用CGLIB代理
@Retryable标记当前方法会使用重试机制。
属性类型默认值阐明
interceptorString“”将interceptor的bean名称应用到retryable(),和其他的属性互斥
includeClass[]{}哪些非常可以触发重试 ,默认为空
excludeClass[]{}哪些非常将不会触发重试,默认为空,如果和include属性同时为空,则所有的非常都将会触发重试
valueClass[]{}可重试的非常类型
labelString“”统计陈诉的唯—标签。如果没有提供,调用者可以选择忽略它,或者提供默认值
maxAttemptsint3尝试的最大次数(包括第一次失败),默认为3次
backoff@Backoff@Backoff()@Backoff @Backoff()指定用于重试此操作的backoff属性。默认为
@Backoff重试回退计谋(立即重试照旧等待一会再重试)
属性类型默认值阐明
delaylong0如果不设置则默认使用1000 ms等待重试,和value同义词
maxDelaylong0最大重试等待时间
multiplierlong0用于盘算下一个延长延长的乘数(大于0生效)
randombooleanFALSE随机重试等待时间
@Backoff 的参数会影响我们使用哪种退避计谋

  • FixedBackOffPolicy默认退避计谋,每 1 秒重试 1 次
  • ExponentialBackOffPolicy指数退避计谋,当设置 multiplier 时使用,每次重试时间间隔为 当前延长时间 * multiplier。
  • ExponentialRandomBackOffPolicy指数随机退避计谋。在指数退避计谋的基础上增加了随机性。具体计谋查看 getSleepAndIncrement() 方法
  • UniformRandomBackOffPolicy均匀随机计谋,设置 maxDely 但没有设置 multiplier 时使用,重试间隔会在 maxDelay 和 delay 间随机
@Recover作为恢复处理程序的方法调用的注释。重试方法最终会调用标注了@Recover 的方法。
@Recover声明的方法和@Retryable 方法相同类型的返回值,Throwable 第一个参数是可选的(但是,如果没有其他参数匹配,则不带该参数的方法将被调用)。从失败方法的参数列表中依次填充后续参数。
v注意事项


  • 使用了Spring-Retry是通过捕获非常的方式来触发重试的,@Retryable注解的方法直接实例化调用不会触发重试,要先将实现类实例化到Spring容器中,然后通过注入等方式使用
  • Spring-Retry是通过捕获非常的方式来触发重试的,@Retryable标注方法产生的非常不能使用try-catch捕获,要在方法上抛出非常,否则不会触发重试
  • recover方法的返回值必须与Spring-Retry是通过捕获非常的方式来触发重试的,@Retryable方法一致
  • 查询可以进行重试,写操作要慎重,除非业务方支持重入
v源码地点

https://github.com/toutouge/javademosecond/tree/master/hellolearn

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

滴水恩情

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表