自己动手实践 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 ...
随机推荐
- 互联网App应用程序测试流程及测试总结
互联网App应用程序测试流程及测试总结 1. APP测试基本流程 1.1流程图 仍然为测试环境 Pass 1.2测试周期 测试周期可按项目的开发周期来确定测试时间,一般测试时间为两三周(即15个工作日 ...
- 支付宝当面付开发(java)
支付宝当面付开发(java) 业务流程: 接入准备: 直接下载demo: https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7 ...
- spring如何控制事务
Spring 的事务,可以说是 Spring AOP 的一种实现. AOP面向切面编程,即在不修改源代码的情况下,对原有功能进行扩展,通过代理类来对具体类进行操作. spring是一个容器,通过spr ...
- .30-浅析webpack源码之doResolve事件流(1)
这里所有的插件都对应着一个小功能,画个图整理下目前流程: 上节是从ParsePlugin中出来,对'./input.js'入口文件的路径做了处理,返回如下: ParsePlugin.prototype ...
- 关于jquery ajax跨域请求获取response headers问题
背景:最近项目jwt用户认证方式,关于jwt本人就不再赘述,大家可自行百度. jwt token基本流程是这样的: 用户使用用户名密码来请求服务器 服务器进行验证用户的信息 服务器通过验证发送给用户一 ...
- 从零开始学习前端开发 — 6、CSS布局模型
一.css布局模型 1.流动模型(Flow) 元素在不设置css样式时的布局模型,是块元素就独占一行,是内联元素就在一行逐个进行显示 2.浮动模型(Float) 使用float属性来进行网页布局,给元 ...
- A glance at endpoint security
Last year hackers stole millions from Taiwan First Commercial bank's ATMs without using a card. This ...
- 微信公众号tp3.2放进Model无效,几种实例化的方法试过,还是提示无法提供服务
http://www.imooc.com/video/10230 解决方案一: $indexModel = D('Index'); 实测可行 解决方案一: 使用TP3.2的小伙伴需要注意了,在Mod ...
- Web前端学习(1):上网的过程与网页的本质
"众里寻他千百度"--但是在信息化时代,我们只需要动动手指百度一下,google一下,便可以在网络上寻得我们想要查找的信息.我们或许都知道要如何在网上获得自己所需信息,但是上网的过 ...
- java实现最小生成树的prim算法和kruskal算法
在边赋权图中,权值总和最小的生成树称为最小生成树.构造最小生成树有两种算法,分别是prim算法和kruskal算法.在边赋权图中,如下图所示: 在上述赋权图中,可以看到图的顶点编号和顶点之间邻接边的权 ...