网站首页 > 技术教程 正文
在分布式系统中,为了保证数据分布式事务的强一致性,大家在调用RPC接口或者发送MQ时,针对可能会出现网络抖动请求超时情况采取一下重试操作。大家用的最多的重试方式就是MQ了,但是如果你的项目中没有引入MQ,那就不方便了,本文主要介绍一下如何使用Spring Retry实现重试操作。
1. 添加maven依赖
[html] view plain
copy
1. <dependency> 2. <groupId>org.springframework.retry</groupId> 3. <artifactId>spring-retry</artifactId> 4. <version>1.1.2.RELEASE</version> 5. </dependency> 6. <dependency> 7. <groupId>org.aspectj</groupId> 8. <artifactId>aspectjweaver</artifactId> 9. <version>1.5.4</version> 10. </dependency>
2. 在启动里添加重试配置
[html] view plain
copy
1. @SpringBootApplication 2. @EnableRetry 3. public class Application { 4. 5. public static void main(String[] args) { 6. SpringApplication.run(Application.class, args); 7. } 8. 9. } 3. 编写Service
[html] view plain
copy
1. @Service 2. public class RemoteService { 3. 4. private static final Logger logger = LoggerFactory.getLogger(TestController.class); 5. 6. @Retryable(value= {BusinessException.class},maxAttempts = 3,backoff = @Backoff(delay = 5000l,multiplier = 2)) 7. public void call() throws Exception { 8. logger.info("do something..."); 9. throw new BusinessException("RPC调用异常"); 10. } 11. @Recover 12. public void recover(BusinessException e) { 13. logger.info(" --------------------------- "); 14. logger.info(e.getMessage()); 15. } 16. }
4. 编写Controller
[html] view plain
copy
1. @RestController 2. @RequestMapping("/test") 3. public class TestController { 4. 5. private static final Logger logger = LoggerFactory.getLogger(TestController.class); 6. 7. @Autowired 8. private RemoteService remoteService; 9. 10. @RequestMapping("/test") 11. public String login() throws Exception { 12. remoteService.call(); 13. return String.valueOf("11"); 14. }
5. 访问http://localhost:8080/test/test
6. 测试日志
[html] view plain
copy
1. 2017-07-25 19:28:07 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.call(RemoteService.java:19)] do something... 2. 2017-07-25 19:28:12 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.call(RemoteService.java:19)] do something... 3. 2017-07-25 19:28:22 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.call(RemoteService.java:19)] do something... 4. 2017-07-25 19:28:22 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.recover(RemoteService.java:24)] --------------------------- 5. 2017-07-25 19:28:22 [INFO]-[http-nio-53602-exec-1]-[com.test.retry.service.RemoteService.recover(RemoteService.java:25)] RPC调用异常
7. 相关配置说明
@EnableRetry能否重试。当proxyTargetClass属性为true时,使用CGLIB代理。默认使用标准JAVA注解。在spring Boot中此参数写在程序入口即可。
@Retryable 标注此注解的方法在发生异常时会进行重试
value:指定处理的异常类
include:指定处理的异常类和value一样,默认为空,当exclude也为空时,默认所有异常
exclude:指定异常不处理,默认空,当include也为空时,默认所有异常
maxAttempts:最大重试次数。默认3次
backoff:重试等待策略。默认使用@Backoff注解
@Backoff 重试等待策略
不设置参数时,默认使用FixedBackOffPolicy(指定等待时间),重试等待1000ms
设置delay,使用FixedBackOffPolicy(指定等待时间),重试等待填写的时间
设置delay和maxDealy时,重试等待在这两个值之间均态分布
设置delay、maxDealy、multiplier,使用 ExponentialBackOffPolicy(指数级重试间隔的实现),multiplier即指定延迟倍数,比如delay=5000l,multiplier=2,则第一次重试为5秒,第二次为10秒,第三次为20秒……
@Recover 用于@Retryable重试失败后处理方法,此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。
springboot 整合retry
加入依赖:
<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@EnableRetrypublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
定义一个简单的controller层:
@RestControllerpublic class HelloController {
Logger logger =LoggerFactory.getLogger(getClass());
@Autowired
private PayService payService;
@GetMapping("/createOrder")
public String createOrder(@RequestParamint num) throws Exception{
int remainingnum= payService.minGoodsnum(num == 0 ? 1: num);
logger.info("剩余的数量==="+remainingnum);
return "库库存成功";
}
}
在controller中调用减库存的service接口,
@Servicepublic 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) throwsException{
logger.info("minGoodsnum开始"+ LocalTime.now());
if(num <= 0){
thrownew Exception("数量不对");
}
logger.info("minGoodsnum执行结束");
return totalNum- num;
}
}
在minGoodsnum方法上加上@Retryable注解,value值表示当哪些异常的时候触发重试,maxAttempts表示最大重试次数默认为3,delay表示重试的延迟时间,multiplier表示上一次延时时间是这一次的倍数。
重试三次抛出异常。
使用@Recover注解,当重试次数达到设置的次数的时候,还是失败抛出异常,执行的回调函数。
猜你喜欢
- 2024-09-25 屡败屡战RETRY第六关关卡攻略 屡屡败屡战的意思
- 2024-09-25 基于redis实现的分布式队列 基于 redis 实现分布式锁是?
- 2024-09-25 .NET 使用 mysql 时 EnableRetryOnFailure() 函数的作用及注意事项
- 2024-09-25 新连载漫画大作导视(十月篇) 十日十月漫画作家
- 2024-09-25 基于guava的重试组件Guava-Retryer
- 2024-09-25 我是怎样得到AO3内容的 我是怎样得到ao3内容的英文
- 2024-09-25 Spring Boot 中使用 spring-retry 轻松解决重试
- 2024-09-25 Java重试利器之Guava-Retryer retry java
- 2024-09-25 springCloud负载均衡机制 springcloud负载均衡策略有哪些
- 2024-09-25 LabVIEW调用DLL中一、二级指针参数及打包exe运行异常的解决办法
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- sd分区 (65)
- raid5数据恢复 (81)
- 地址转换 (73)
- 手机存储卡根目录 (55)
- tcp端口 (74)
- project server (59)
- 双击ctrl (55)
- 鼠标 单击变双击 (67)
- debugview (59)
- 字符动画 (65)
- flushdns (57)
- ps复制快捷键 (57)
- 清除系统垃圾代码 (58)
- web服务器的架设 (67)
- 16进制转换 (69)
- xclient (55)
- ps源文件 (67)
- filezilla server (59)
- 句柄无效 (56)
- word页眉页脚设置 (59)
- ansys实例 (56)
- 6 1 3固件 (59)
- sqlserver2000挂起 (59)
- vm虚拟主机 (55)
- config (61)
本文暂时没有评论,来添加一个吧(●'◡'●)