自己动手实践 spring retry 重试框架
前序
马上过年了,预祝大家,新年快乐,少写bug
什么是spring retry?
spring retry是从spring batch独立出来的一个能功能,主要实现了重试和熔断。
什么时候用?
远程调用超时、网络突然中断可以重试。对于重试是有场景限制的,不是什么场景都适合重试,比如参数校验不合法、写操作等(要考虑写是否幂等)都不适合重试。
怎么用?
1,首先我们新建一个maven工程(如果不会,请移步 http://www.cnblogs.com/JJJ1990/p/8384386.html,大佬请忽略),然后在pom文件中引入spring retry 的jar包,代码如下:
<!-- spring-retry重试机制 -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
2,编写重试部分代码,我们直接在app类的main方法中实现
首先我们先制定好重试策略,也就是当异常发生后,我们重试几次,每次间隔多久等
如下代码中,第一行为新建一个重试模板,第二行为制定一个简单重试策略,特别注意最后的数字3,这就是我们设置的要重试的次数
final RetryTemplate retryTemplate = new RetryTemplate();
final SimpleRetryPolicy policy = new SimpleRetryPolicy(3,
Collections.<Class<? extends Throwable>,
Boolean>singletonMap(Exception.class, true));
3,下面再设置退避策略,注意第二行 2000为每次间隔的时间,单位ms,然后再将 重试策略和退避策略设置到重试模板中如第3.4行
FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
fixedBackOffPolicy.setBackOffPeriod(2000);
retryTemplate.setRetryPolicy(policy);
retryTemplate.setBackOffPolicy(fixedBackOffPolicy);
4,编写重试业务部分代码如下,主要是实现RetryCallback接口的 doWithRetry 方法,在这个里面就是编写主要的业务逻辑了。我在这块模拟了一个异常,通过数组下标越界异常,来进行重试
final RetryCallback<String, Exception> retryCallback = new RetryCallback<String, Exception>() {
public String doWithRetry(RetryContext context) throws Exception {
System.out.println(new Date());
System.out.println("retryCallback");
String [] str = new String [2];
str[3] = "";
return "1";
}
};
5,编写恢复回调代码如下,也是实现了RecoveryCallback接口中的recover方法,这个方法的作用就是当第4步重试代码按照重试策略执行完毕后,依旧异常,那就会执行下面的代码,这样你就可以通过下面的代码,来规避异常
final RecoveryCallback<String> recoveryCallback = new RecoveryCallback<String>() {
public String recover(RetryContext context) throws Exception {
System.out.println("recoveryCallback");
return null;
}
};
6,编写重试模板执行重试代码及恢复回调代码
try {
System.out.println("retryTemplate execute start");
String response = retryTemplate.execute(retryCallback, recoveryCallback);
System.out.println("retryTemplate execute end");
} catch (Exception e) {
e.printStackTrace();
}
测试代码
启动程序,注意整个代码是全部在main方法中实现的,我们直接启动程序看打印的日志信息,从日志信息中可以得知,我们在启动程序后先进入execute方法,然后执行retrycallback,但是每次执行的时候都有数组下标越觉异常,所以他就重试了3次,而且每次的时间间隔是我们设置的2秒,当第三次执行失败后,就调用recovercallback方法,然后整个程序结束。
退别策略有哪些?
1,我们上面的代码中用的退别策略是固定时间间隔,还有其他几种的退避策略大致如下:
NoBackOffPolicy:无退避算法策略,每次重试时立即重试
FixedBackOffPolicy:固定时间的退避策略,需设置参数sleeper和backOffPeriod,sleeper指定等待策略,默认是Thread.sleep,即线程休眠,backOffPeriod指定休眠时间,默认1秒
UniformRandomBackOffPolicy:随机时间退避策略,需设置sleeper、minBackOffPeriod和maxBackOffPeriod,该策略在[minBackOffPeriod,maxBackOffPeriod之间取一个随机休眠时间,minBackOffPeriod默认500毫秒,maxBackOffPeriod默认1500毫秒
ExponentialBackOffPolicy:指数退避策略,需设置参数sleeper、initialInterval、maxInterval和multiplier,initialInterval指定初始休眠时间,默认100毫秒,maxInterval指定最大休眠时间,默认30秒,multiplier指定乘数,即下一次休眠时间为当前休眠时间*multiplier
ExponentialRandomBackOffPolicy:随机指数退避策略,引入随机乘数可以实现随机乘数回退
我们将第3步的代码进行修改,如下:
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
exponentialBackOffPolicy.setInitialInterval(2000);
exponentialBackOffPolicy.setMultiplier(3);
exponentialBackOffPolicy.setMaxInterval(5000);
retryTemplate.setRetryPolicy(policy);
retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
上述代码中,2000为执行的时间间隔,3为倍数,5000为允许的最大间隔时间,执行代码结果如下:
如上图,第一次执行和第二次执行间隔2秒,第二次和第三次的间隔本来是2*3=6秒,但是由于设置了最大间隔所以在5秒的时候就触发了重试
重试业务中的异常不要捕获
在我们的重试业务代码中我们需要根据异常来进行重试,如果你在业务代码中捕获了异常会怎么样??我们修改下第4步代码看看:
final RetryCallback<String, Exception> retryCallback = new RetryCallback<String, Exception>() {
public String doWithRetry(RetryContext context) throws Exception {
System.out.println(new Date());
System.out.println("retryCallback");
try {
String [] str = new String [2];
str[3] = "";
} catch (Exception e) {
// TODO: handle exception
} return "1";
}
};
如上,很简单,我们直接将数组异常try catch ,然后运行代码结果如下
如上图,从信息中可以看出,本来异常的代码只执行了一次,而且没有调用恢复回调代码。
所以如果你需要执行重试,那么就不要捕获你需要重试的异常信息。
所以如果你需要执行重试,那么就不要捕获你需要重试的异常信息。
所以如果你需要执行重试,那么就不要捕获你需要重试的异常信息。
重要的话说三遍~~~
自己动手搭建一个简易的SpringBoot环境
自己动手实践 spring retry 重试框架的更多相关文章
- Spring异常重试框架Spring Retry
Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...
- Spring Retry 重试
重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说 ...
- 012 spring retry重试原理的解析
有点复杂,在后续的章节,将会对其中涉及到的知识点,再分章节进行说明. 1.程序结构 2.@Retryable package com.jun.web.annotation.theory; import ...
- spring retry 重试机制完整例子
public static Boolean vpmsRetryCoupon(final String userId) { // 构建重试模板实例 RetryTemplate retryTemplate ...
- 异常重试框架Spring Retry实践
前期准备在Maven项目中添加Spring Retry和切面的依赖 POM: <!-- Spring Retry --> <dependency> <groupId> ...
- Spring retry实践
在开发中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络波动出现超时而采取重试手段......可以看见重试操作是非常常见的一种处理问题, ...
- Spring错误异常重试框架guava-retrying
官网:https://github.com/rholder/guava-retrying Maven:https://mvnrepository.com/artifact/com.github.rho ...
- Spring框架中一个有用的小组件:Spring Retry
1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spri ...
- 自己动手写Spring框架--IOC、MVC
对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...
随机推荐
- Xtrabackup实现数据的备份与恢复
Xtrabackup介绍 Xtrabackup是由percona开源的免费数据库热备份软件,它能对InnoDB数据库和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同样需要加表锁): ...
- [国嵌攻略][119][Linux中断处理程序设计]
裸机中断: 1.中断统一入口. 2.注册中断处理程序. 3.根据中断源编号,调用中断处理程序. Linux中断 1.在entry-armv.S中的_irq_svc是中断统一入口. 2.获取产生中断源的 ...
- Tree Recovery(由先、中序列构建二叉树)
题目来源: http://poj.org/problem?id=2255 题目描述: Description Little Valentine liked playing with binary tr ...
- 引导图滤波(Guided Image Filtering)原理以及OpenCV实现
引导图是一种自适应权重滤波器,能够在平滑图像的同时起到保持边界的作用,具体公式推导请查阅原文献<Guided Image Filtering>.这里只说一下自适应权重原理.C++实现灰度图 ...
- Dubbo底层采用Socket进行通信详解
由于Dubbo底层采用Socket进行通信,自己对通信理理论也不是很清楚,所以顺便把通信的知识也学习一下. n 通信理论 计算机与外界的信息交换称为通信.基本的通信方法有并行通信和串行通信两种. 1 ...
- myeclipse编码
window --->perferences
- 微信小程序左右滑动切换图片酷炫效果(附效果)
开门见山,先上效果吧!感觉可以的用的上的再往下看. 心动吗?那就继续往下看! 先上页面结构吧,也就是wxml文件,其实可以理解成微信自己封装过的html,这个不多说了,不懂也没必要往下看了. < ...
- scrapy_随机user-agent
什么是user-agent? 用户代理,服务器识别用户的操作系统,浏览器类型和渲染引擎,不同浏览器的user-agent是不同的 如何随机更改user-agent? 1. 在setting中添加use ...
- python_斐波那契数列
什么是斐波那契数列? -- 一组第从第三个值开始,每个值都等于前两个值之和的一种有意思的数列 如[1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 如何用程序进行实现? -- 逻辑整 ...
- .net Core学习笔记3 编辑列表并绑定下拉列
本次主要实现列表的编辑及下拉列表的绑定 先看效果图: 主要用DropDownList绑定下拉列后端代码: 1:定义一个存下拉数据类 public class SelectItem { public s ...