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

写一个简单的demo,加入依赖:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
</dependencies>

在主类上加上@EnableRetry注解,表示启用重试机制。

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

定义一个简单的controller层:

@RestController
public class HelloController { Logger logger = LoggerFactory.getLogger(getClass()); @Autowired
private PayService payService; @GetMapping("/createOrder")
public String createOrder(@RequestParam int num) throws Exception{
int remainingnum = payService.minGoodsnum(num == 0 ? 1: num);
logger.info("剩余的数量==="+remainingnum);
return "库库存成功";
} }

在controller中调用减库存的service接口,

@Service
public class PayService { private Logger logger = LoggerFactory.getLogger(getClass()); private final int totalNum = 100000; @Retryable(value = Exception.class,maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 1.5))
public int minGoodsnum(int num) throws Exception{
logger.info("minGoodsnum开始"+ LocalTime.now());
if(num <= 0){
throw new Exception("数量不对");
}
logger.info("minGoodsnum执行结束");
return totalNum - num;
}
}

在minGoodsnum方法上加上@Retryable注解,value值表示当哪些异常的时候触发重试,maxAttempts表示最大重试次数默认为3,delay表示重试的延迟时间,multiplier表示上一次延时时间是这一次的倍数。

测试:

 
图片.png
 
图片.png

重试三次抛出异常。

使用@Recover注解,当重试次数达到设置的次数的时候,还是失败抛出异常,执行的回调函数。

关于@Recover注解

 
图片.png

和minGoodsnum定义在一个类中

@Recover
public int recover(Exception e){
logger.warn("减库存失败!!!");
//记日志到数据库
return totalNum;
}

重试测试一下,

 
图片.png

感觉意义不大,重试失败的时候应该还是要抛出异常的,在上层进行catch记录日志,当然也有特殊的场景适用。

作者:二月_春风
链接:https://www.jianshu.com/p/314059943f1c
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

springboot 整合retry(重试机制)的更多相关文章

  1. Java之Retry重试机制详解

    应用中需要实现一个功能: 需要将数据上传到远程存储服务,同时在返回处理成功情况下做其他操作.这个功能不复杂,分为两个步骤:第一步调用远程的Rest服务上传数据后对返回的结果进行处理:第二步拿到第一步结 ...

  2. spring retry 重试机制完整例子

    public static Boolean vpmsRetryCoupon(final String userId) { // 构建重试模板实例 RetryTemplate retryTemplate ...

  3. springboot系列——重试机制原理和应用,还有比这个讲的更好的吗(附完整源码)

    1. 理解重试机制 2. 总结重试机制使用场景 3. spring-retry重试组件 4. 手写一个基于注解的重试组件 5. 重试机制下会出现的问题 6. 模板方法设计模式实现异步重试机制 如果有, ...

  4. 功能:SpringBoot整合rabbitmq,长篇幅超详细

    SpringBoot整合rabbitMq 一.介绍 消息队列(Message Queue)简称mq,本文将介绍SpringBoot整合rabbitmq的功能使用 队列是一种数据结构,就像排队一样,遵循 ...

  5. 自己动手实践 spring retry 重试框架

    前序 马上过年了,预祝大家,新年快乐,少写bug 什么是spring retry? spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断. 什么时候用? 远程 ...

  6. SpringBoot整合RabbitMQ-整合演示

    本系列是学习SpringBoot整合RabbitMQ的练手,包含服务安装,RabbitMQ整合SpringBoot2.x,消息可靠性投递实现等三篇博客. 学习路径:https://www.imooc. ...

  7. SpringCloud | FeignClient和Ribbon重试机制区别与联系

    在spring cloud体系项目中,引入的重试机制保证了高可用的同时,也会带来一些其它的问题,如幂等操作或一些没必要的重试. 今天就来分别分析一下 FeignClient 和 Ribbon 重试机制 ...

  8. Spring Cloud重试机制与各组件的重试总结

    SpringCloud重试机制配置 首先声明一点,这里的重试并不是报错以后的重试,而是负载均衡客户端发现远程请求实例不可到达后,去重试其他实例. ? 1 2 3 4 5 6 7 8 @Bean @Lo ...

  9. ribbon重试机制

    我们使用Spring Cloud Ribbon实现客户端负载均衡的时候,通常都会利用@LoadBalanced来让RestTemplate具备客户端负载功能,从而实现面向服务名的接口访问. 下面的例子 ...

随机推荐

  1. IDEA突然无法运行

    可能是你类的main方法被idea的智能提示改了 PS: 小编经常用智能提示,它给我把main方法的static关键字删掉了好几次,当时怎么也没想到是把main方法改了 ~难受

  2. mysql数据库运维方案

    数据库不仅仅是dba的工作,每一个测试人员也应该懂得基本的数据运维操作,因为数据库是数据承载的地方并且是系统中非常重要的一部分,所以我们也需要熟练的对数据库进行基本维护. 01.常用备份恢复命令 第1 ...

  3. jenkins 添加用户管理权限

    一.前言 小组开会通知 想把jenkins 构建的权限给开发,这样的话效率会增加.运维也不必每次帮助开发去构建发布. 1.规划 jenkins 四个项目分别对应三个人负责.项目下的只负责 CI.UAT ...

  4. JNI_day01

    C语言简介 system()是提供C语言调用系统命令的函数 C语言基本数据类型 C语言中的整数类型:char/short/int/long C中使用ASCII保存字符,所以char所占用的字节数为1 ...

  5. Spring之多数据源切换的应用

    这不是一个新的知识点扩展,顶多算是,Spring的AOP特性的一个应用.那么下面开始今天的学习之旅! 场景 数据库读写分离,或者分库,总之多数据源的场景,怎么样实现自动切换(PS:不考虑各种分库分表的 ...

  6. eurekaAutoServiceRegistration 异常

    方案来自:https://github.com/spring-cloud/spring-cloud-netflix/issues/1952 解决办法: @Component public class ...

  7. (六)获取http状态码和处理返回结果

    int StatusCode = httpResponse.getStatusLine().getStatusCode(); 处理返回结果: /** * 处理返回结果 * @param respons ...

  8. 命令中"|"的意义

    管道命令,是指 | 的左边运行结果是|右边的输入条件或者范围.如:history | grep date指从history这条命令运行的结果中显示包含有 “date” 的命令 下面举一个例子: 这是运 ...

  9. python中的importlib包

    importlib.import_module(name, package=None) 导入一个模块.参数 name 指定了以绝对或相对导入方式导入什么模块 (比如要么像这样 pkg.mod 或者这样 ...

  10. 【JMeter_15】JMeter逻辑控制器__仅一次控制器<Once Only Controller>

    仅一次控制器<Once Only Controller> 业务逻辑: 在每个线程内,该控制器下的内容只会被执行一遍,无论循环多少次,都只执行一遍.<嵌套在循环控制器之内时是个例外,每 ...