011 @Retryable的使用
时间:2019-08-23
本文章向大家介绍011 @Retryable的使用,主要包括011 @Retryable的使用使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一:概述
在调用第三方接口或者使用mq时,会出现网络抖动,连接超时等网络异常,所以需要重试。
为了使处理更加健壮并且不太容易出现故障,后续的尝试操作,有时候会帮助失败的操作最后执行成功。
例如,由于网络故障或数据库更新中的DeadLockLoserException导致Web服务或RMI服务的远程调用可能会在短暂等待后自行解决。 为了自动执行这些操作的重试,Spring Batch具有RetryOperations策略。不过该重试功能从Spring Batch 2.2.0版本中独立出来,变成了Spring Retry模块。
二:示例
1.pom
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency>
2.配置类
只有启用@EnabelRetry才行,写在配置类或者启动类上都是可以的
package com.jun.web.config; import org.springframework.context.annotation.Configuration; import org.springframework.retry.annotation.EnableRetry; @Configuration @EnableRetry public class RetryConfig { }
3.服务类
一般将其加到服务类上就行,服务类一般写主要逻辑
package com.jun.web.annotation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Recover; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import java.time.LocalTime; @Service public class PayService { private Logger logger = LoggerFactory.getLogger(getClass()); private final int totalNum = 100000; @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000L, multiplier = 1.5)) public int minGoodsnum(int num) throws Exception { logger.info("减库存开始" + LocalTime.now()); try { int i = 1 / 0; } catch (Exception e) { logger.error("illegal"); } if (num <= 0) { throw new IllegalArgumentException("数量不对"); } logger.info("减库存执行结束" + LocalTime.now()); return totalNum - num; } @Recover public int recover(Exception e) { logger.warn("减库存失败!!!" + LocalTime.now()); //记日志到数据库 return totalNum; } }
4.测试
package com.jun.web.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class PayController { @Autowired private PayService payService; @GetMapping("/retry") public String getNum() throws Exception { int i = payService.minGoodsnum(-1); System.out.println("===="+i); return "succeess"; } }
5.结果
2019-08-23 10:27:46.702 DEBUG 16036 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : GET "/retry", parameters={} 2019-08-23 10:27:46.702 DEBUG 16036 --- [nio-8080-exec-5] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public java.lang.String com.jun.web.annotation.PayController.getNum() throws java.lang.Exception 2019-08-23 10:27:46.703 INFO 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : 减库存开始10:27:46.703 2019-08-23 10:27:46.703 ERROR 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : illegal 2019-08-23 10:27:48.703 INFO 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : 减库存开始10:27:48.703 2019-08-23 10:27:48.703 ERROR 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : illegal 2019-08-23 10:27:51.704 INFO 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : 减库存开始10:27:51.704 2019-08-23 10:27:51.704 ERROR 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : illegal 2019-08-23 10:27:51.704 WARN 16036 --- [nio-8080-exec-5] com.jun.web.annotation.PayService : 减库存失败!!!10:27:51.704 ====100000 2019-08-23 10:27:51.704 DEBUG 16036 --- [nio-8080-exec-5] m.m.a.RequestResponseBodyMethodProcessor : Using 'text/html', given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, */*;q=0.8] and supported [text/plain, */*, text/plain, */*, application/json, application/*+json, application/json, application/*+json] 2019-08-23 10:27:51.704 DEBUG 16036 --- [nio-8080-exec-5] m.m.a.RequestResponseBodyMethodProcessor : Writing ["succeess"] 2019-08-23 10:27:51.705 DEBUG 16036 --- [nio-8080-exec-5] o.s.web.servlet.DispatcherServlet : Completed 200 OK 2019-08-23 10:27:51.714 DEBUG 16036 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : GET "/favicon.ico", parameters={} 2019-08-23 10:27:51.715 DEBUG 16036 --- [nio-8080-exec-6] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped to ResourceHttpRequestHandler [class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], ServletContext resource [/], class path resource []] 2019-08-23 10:27:51.718 DEBUG 16036 --- [nio-8080-exec-6] o.s.web.servlet.DispatcherServlet : Completed 200 OK
三:说明
1.@Retryable参数的意思说明
- value:抛出指定异常才会重试
- include:和value一样,默认为空,当exclude也为空时,默认所以异常
- exclude:指定不处理的异常
- maxAttempts:最大重试次数,默认3次
- backoff:重试等待策略,默认使用
@Backoff
,@Backoff
的value默认为1000L,我们设置为2000L;multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
2.Recover注解
当重试耗尽时,RetryOperations可以将控制传递给另一个回调,即RecoveryCallback。Spring-Retry还提供了@Recover注解,用于@Retryable重试失败后处理方法,此方法里的异常一定要是@Retryable方法里抛出的异常,否则不会调用这个方法。
从上面的结果上可以看出来。
原文地址:https://www.cnblogs.com/juncaoit/p/11398547.html
- 智能下拉刷新框架-SmartRefreshLayout
- Spring Cloud(三)服务提供者 Eureka + 服务消费者(rest + Ribbon)
- Spring Cloud(二)Consul 服务治理实现
- Spring Cloud(一)服务的注册与发现(Eureka)
- Shard 分片集群
- 面试官最爱的volatile关键字
- 玩转 WebView ,突破系统限制,让缓存更简单,更灵活
- Mycat 读写分离 数据库分库分表 中间件 安装部署,及简单使用
- 50道Java线程题
- Jrebel6.3.3破解,配置图文教程
- Spring Cloud(十一)高可用的分布式配置中心 Spring Cloud Bus 消息总线集成(RabbitMQ)
- Keras中带LSTM的多变量时间序列预测
- Spring Cloud(十)高可用的分布式配置中心 Spring Cloud Config 中使用 Refresh
- Hibernate 的性能优化的时候碰到了"抓取策略",有四种
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Flutter 强大的MediaQuery控件
- 基于web的图书管理系统设计与实现
- 《Flutter 动画系列一》25种动画组件超全总结
- 网工小白升级打怪篇(三)ssh实现远程管理
- 贪吃蛇的使命 | 零基础入门贪吃蛇游戏(附源码、演示地址)
- Java开发岗面试题--基础篇(二)
- C++核心准则T.48:如果你的编译器不支持concepts,使用enable_if模仿它
- 《Flutter 动画系列》组合动画
- Flutter 完美的验证码输入框
- 【送红宝书】JavaScript 测试系列实战(四):掌握 React Hooks 测试技巧
- Spring 自定义注解你了解过吗?
- 《Flutter 小技巧》一行禁用App,一行置灰App,致敬
- 字符串:总结篇!
- 3 个助你玩转正则表达式的利器
- Flutter 实现虎牙/斗鱼 弹幕效果