@Retryable

前言

在实际工作中,重处理是一个非常常见的场景,比如:

  • 发送消息失败。
  • 调用远程服务失败。
  • 争抢锁失败。

这些错误可能是因为网络波动造成的,等待过后重处理就能成功。通常来说,会用try/catchwhile循环之类的语法来进行重处理,但是这样的做法缺乏统一性,并且不是很方便,要多写很多代码。然而spring-retry却可以通过注解,在不入侵原有业务逻辑代码的方式下,优雅的实现重处理功能。

一、@Retryable是什么?

spring系列的spring-retry是另一个实用程序模块,可以帮助我们以标准方式处理任何特定操作的重试。在spring-retry中,所有配置都是基于简单注释的。

二、使用步骤

1.POM依赖

  <!-- 因为是基于AOP实现的 所以引入AOP依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>

2.启用@Retryable

@EnableRetry
@SpringBootApplication
public class TestApplication { public static void main(String[] args) {
SpringApplication.run(TestApplication .class, args);
}
}

3.在方法上添加@Retryable

@Service
public class TestRetryServiceImpl implements TestRetryService { @Override
@Retryable(value = Exception.class,maxAttempts = 10,backoff = @Backoff(delay = 2000,multiplier = 1.5))
public int testRetry(int code, String userName, List<String> list) throws Exception{
System.out.println("testRetry被调用,时间:"+LocalTime.now());
if (code==0){
throw new Exception("发生错误!!!");
}
System.out.println("testRetry被调用,成功!!!"); return 200;
}
}

来简单解释一下注解中几个参数的含义:

  • value:抛出指定异常才会重试
  • include:和value一样,默认为空,当exclude也为空时,默认所有异常
  • exclude:指定不处理的异常
  • maxAttempts:最大重试次数,默认3次
  • backoff:重试等待策略,默认使用@Backoff@Backoff的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。

当重试耗尽时还是失败,会出现什么情况呢?

当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即Spring-Retry还提供了@Recover注解,用于@Retryable`重试失败后处理方法。如果不需要回调方法,可以直接不写回调方法,那么实现的效果是,重试次数完了后,如果还是没成功没符合业务判断,就抛出异常。

4.@Recover

@Recover
public int recover(Exception e, int code, String userName, List<String> list){
System.out.println("回调方法执行!!!!");
//参数的顺序要和上方方法的顺序一致,否则会出现参数类型不匹配
System.out.println(code);
System.out.println(userName);
System.out.println(list);
//记日志到数据库 或者调用其余的方法
return 400;
}

可以看到传参里面写的是 Exception e,这个是作为回调的接头暗号(重试次数用完了,还是失败,我们抛出这个Exception e通知触发这个回调方法)。对于@Recover注解的方法,需要特别注意的是:

  • 方法的返回值必须与@Retryable方法一致
  • 方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover方法中有的)
  • 该回调方法与重试方法写在同一个实现类里面

5. 注意事项

  • 由于是基于AOP实现,所以不支持类里自调用方法
  • 如果重试失败需要给@Recover注解的方法做后续处理,那这个重试的方法不能有返回值,只能是void
  • 方法内不能使用try catch,只能往外抛异常
  • @Recover注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。

@Retryable注解的使用的更多相关文章

  1. 扒一扒@Retryable注解,很优雅,有点意思!

    你好呀,我是歪歪. 前几天我 Review 代码的时候发现项目里面有一坨逻辑写的非常的不好,一眼望去简直就是丑陋之极. 我都不知道为什么会有这样的代码存在项目里面,于是我看了一眼提交记录准备叫对应的同 ...

  2. 关于Spring注解@Async引发其他注解失效

    概述 在前面一篇文章中,介绍,在一个Bean中注入自己,如果有@Async和@Transaction,如果使用@Autowire注入自身,会报循环依赖,如果使用BeanFactoryAware注入自己 ...

  3. 用spring-retry注解自动触发重试方法

    原文地址:https://www.jianshu.com/p/ee02d6125113 需求背景: 有些时候我们再调用一些第三方服务的时候,从第三方那边拉数据. 但是第三方服务不是100%稳定的,有些 ...

  4. 一个注解@Recover搞定丑陋的循环重试代码

    使用背景 在实际项目中其中一部分逻辑可能会因为调用了外部服务或者等待锁等情况下出现不可预料的异常,在这个时候我们可能需要对调用这部分逻辑进行重试,代码里面主要就是使用for循环写一大坨重试的逻辑,各种 ...

  5. Spring异步调用原理及SpringAop拦截器链原理

    一.Spring异步调用底层原理 开启异步调用只需一个注解@EnableAsync @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTI ...

  6. springboot retry

    try/catch,while 循环或者定时任务  这样看起来 好  low sping boot  retry , 这样代码更简洁 eg: @Retryable(value= {RemoteAcce ...

  7. Spring retry实践

    在开发中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络波动出现超时而采取重试手段......可以看见重试操作是非常常见的一种处理问题, ...

  8. Spring异常重试框架Spring Retry

    Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...

  9. 异常重试框架Spring Retry实践

    前期准备在Maven项目中添加Spring Retry和切面的依赖 POM: <!-- Spring Retry --> <dependency> <groupId> ...

  10. springboot 整合retry(重试机制)

    当我们调用一个接口可能由于网络等原因造成第一次失败,再去尝试就成功了,这就是重试机制,spring支持重试机制,并且在Spring Cloud中可以与Hystaix结合使用,可以避免访问到已经不正常的 ...

随机推荐

  1. ClickHouse(05)ClickHouse数据类型详解

    ClickHouse属于分析型数据库,ClickHouse提供了许多数据类型,它们可以划分为基础类型.复合类型和特殊类型.其中基础类型使ClickHouse具备了描述数据的基本能力,而另外两种类型则使 ...

  2. Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):4、Maven项目转换与pom.xml配置

    文章目录: Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):1.JIRA账号注册 Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):2.PGP ...

  3. Exchange 2019数据库切换

    最近在测试Exchange 2019的一些安装步骤.在测试到DAG的数据库切换的时候遇到了一些问题.An Active Manager operation failed. Error: The dat ...

  4. Elasticsearch: Reindex接口

    在我们开发的过程中,我们有很多时候需要用到Reindex接口.它可以帮我们把数据从一个index到另外一个index进行重新reindex.这个对于特别适用于我们在修改我们数据的mapping后,需要 ...

  5. Elasticsearch:运用 shard_size 来提高term aggregation的精度

  6. Elasticsearch索引生命周期管理探索

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484130&idx=1&sn=454f199 ...

  7. Fluentd部署:系统配置

    Fluentd的全局配置项,诸如开启RPC.使用多worker模式等.可在配置文件中通过<system>进行配置,或通过命令行进行配置. 参数 workers:指定worker进程数,默认 ...

  8. AlertManager 之微信告警模板,UTC时间错8个小时的解决办法

    注意事项: alertmanager中的web页面显示的报警时间是UTC时间,错8个小时,企业微信报警模板中已经修改过来了 下面配置可以作为参考: 1.prometheus操作 1.1 配置告警规则, ...

  9. vue基础之MV*和它们之间的不同

    vue中的设计思想 vue中的设计思想主要是MV*模式,由最早的MVC(model-view-controller)框架,到后面的MVP(model-view-presenter),甚至到最后的MVV ...

  10. springboot自动配置原理以及手动实现配置类

    springboot自动配置原理以及手动实现配置类 1.原理 spring有一个思想是"约定大于配置". 配置类自动配置可以帮助开发人员更加专注于业务逻辑开发,springboot ...