前序

马上过年了,预祝大家,新年快乐,少写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 重试框架的更多相关文章

  1. Spring异常重试框架Spring Retry

    Spring Retry支持集成到Spring或者Spring Boot项目中,而它支持AOP的切面注入写法,所以在引入时必须引入aspectjweaver.jar包. 快速集成的代码样例: @Con ...

  2. Spring Retry 重试

    重试的使用场景比较多,比如调用远程服务时,由于网络或者服务端响应慢导致调用超时,此时可以多重试几次.用定时任务也可以实现重试的效果,但比较麻烦,用Spring Retry的话一个注解搞定所有.话不多说 ...

  3. 012 spring retry重试原理的解析

    有点复杂,在后续的章节,将会对其中涉及到的知识点,再分章节进行说明. 1.程序结构 2.@Retryable package com.jun.web.annotation.theory; import ...

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

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

  5. 异常重试框架Spring Retry实践

    前期准备在Maven项目中添加Spring Retry和切面的依赖 POM: <!-- Spring Retry --> <dependency> <groupId> ...

  6. Spring retry实践

    在开发中,重试是一个经常使用的手段.比如MQ发送消息失败,会采取重试手段,比如工程中使用RPC请求外部服务,可能因为网络波动出现超时而采取重试手段......可以看见重试操作是非常常见的一种处理问题, ...

  7. Spring错误异常重试框架guava-retrying

    官网:https://github.com/rholder/guava-retrying Maven:https://mvnrepository.com/artifact/com.github.rho ...

  8. Spring框架中一个有用的小组件:Spring Retry

    1.概述 Spring Retry 是Spring框架中的一个组件, 它提供了自动重新调用失败操作的能力.这在错误可能是暂时发生的(如瞬时网络故障)的情况下很有帮助. 在本文中,我们将看到使用Spri ...

  9. 自己动手写Spring框架--IOC、MVC

    对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC.MVC.AOP.ORM(batis). 下面我想简单介绍一下我写的轻量级的 S ...

随机推荐

  1. centos7 hue安装

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  2. ArcGIS中实现指定面积蜂窝(正六边形)方法

    本篇博文为博主(whgiser)原创,转载请注明. 空间聚集研究中,地理尺度大多数都是基于格网构建的,只需fishnet下就行了.也常有使用社区.交通小区(TZ)作为研究单元的.直到发现蜂窝网络做出的 ...

  3. php短信接口代码

    这篇文章主要为大家详细介绍了php短信接口代码,php短信发送.php批量发送.php获取余额等代码,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了几个常用的php短信接口代码,供大家参考,具体内 ...

  4. Efounds笔试

    Efounds的笔试~ 1.比较两个浮点数大小 一般不会直接用"=="或者"!="对两个浮点数进行比较. 判断两个浮点数float a 与 float b 是否 ...

  5. Python 爬取美女图片,分目录多级存储

    最近有个需求:下载https://mm.meiji2.com/网站的图片. 所以简单研究了一下爬虫. 在此整理一下结果,一为自己记录,二给后人一些方向. 爬取结果如图:   整体研究周期 2-3 天, ...

  6. Mac下Charles Contents乱码解决办法

    用到Charles,下载最新的4.0.1版本,但是发生乱码问题.百度好久才找到个靠谱的,那些说什么在Info.plist文件加字符串的,都是假的,反正我是试了都没用,这里记下详细的操作步骤解决: 1. ...

  7. 提示让IE8以下版本的浏览器去更新浏览器

    需求: 强制让IE进行页面渲染时候,用最新的方式渲染,并提示让IE8以下的版本去更新浏览器并给一个连接地址 那,如何满足? <!DOCTYPE html> <html lang=&q ...

  8. 1.JavaScript 教程:基础语法

    简介: JavaScript web 开发人员必须学习的 3 门语言中的一门: HTML 定义了网页的内容 CSS 描述了网页的布局 JavaScript 网页的行为 用法: (1)HTML 中的脚本 ...

  9. 微信屏蔽js分享、复制链接

    页面内引入js(不放在页面内部不起作用) $(function(){ function onBridgeReady() { WeixinJSBridge.call('hideOptionMenu'); ...

  10. sqlserver 字符串截取与拼接

    update yanan set name=name+right(phone,4) where id=56 其中right(phone,4)是截取手机号后四位,left是从左开始截取.name=nam ...