重试机制(1.0)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
工作中遇到需要远程调用,测试被调用方是否正常,类似心跳机制一样
提示:以下是本篇文章正文内容,下面案例可供参考
一、重试机制特性+使用场景
特性:
无侵入
可配置
通用性
使用场景:
适用,远程调用超时,网络中断重试
不适用,参数校验不合法,写操作,幂等性
重试共性:
需要实例作为媒介
约定重试间隔
都是通过委托重试对象完成相应逻辑,内部封装重试方法
二、使用步骤
1.简单的手动重试方法
在平时的开发工作中,重试机制,是一个很重要的逻辑,比如调用其他服务时,如果出现超时,那么可以等100毫秒后再进行调用,或者出现异常时,需要重试;可以重试多次,也可以重试1次,这个都是可以在程序中设定的。
实现上面的逻辑,最简单的方式就是使用for循环了
代码如下(示例):
package cn.ganlixin.guava;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UseRetryer {
private static final Logger log = LoggerFactory.getLogger(UseRetryer.class);
@Test
public void testUseFor() throws InterruptedException {
int retryTimes = 3; // 重试次数
// 使用for循环控制重试
for (int i = 0; i < retryTimes; i++) {
try {
// 逻辑代码,比如调用其他服务的接口
} catch (Exception e) {
log.warn("第{}次运行出现异常,", i);
// 如果出现异常,休眠100毫秒后重试(继续for循环)
Thread.sleep(100);
continue;
}
// 执行成功,立即终止for循环。
break;
}
}
}
2.spring自带重试机制
代码如下(示例):
1.引入依赖
2.启用:
(1)启动类加上注解
@EnableRetry
3.使用:
在需要重试的方法上加上
* value:抛出指定异常才会重试
* include:和value一样,默认为空,当exclude也为空时,默认所有异常
* exclude:指定不处理的异常
* maxAttempts:最大重试次数,默认3次
* backoff:重试等待策略,
* 默认使用@Backoff,@Backoff的value默认为1000L,我们设置为2000; 以毫秒为单位的延迟(默认 1000)
* multiplier(指定延迟倍数)默认为0,表示固定暂停1秒后进行重试,如果把multiplier设置为1.5,则第一次重试为2秒,第二次为3秒,第三次为4.5秒。
4.异常处理:
默认情况以上已经可以执行重试,但是对于指定的重试次数后,继续失败,仍然会抛出异常,对此可以做以下操作
在开启重试机制的方法下面新建回调方法
@Recover
注意事项:
* 方法的返回值必须与@Retryable方法一致
* 方法的第一个参数,必须是Throwable类型的,建议是与@Retryable配置的异常一致,其他的参数,需要哪个参数,写进去就可以了(@Recover方法中有的)
* 该回调方法与重试方法写在同一个实现类里面
* 由于是基于AOP实现,所以不支持类里自调用方法
* 如果重试失败需要给@Recover注解的方法做后续处理,那这个重试的方法不能有返回值,只能是void
* 方法内不能使用try catch,只能往外抛异常
* @Recover注解来开启重试失败后调用的方法(注意,需跟重处理方法在同一个类中),此注解注释的方法参数一定要是@Retryable抛出的异常,否则无法识别,可以在该方法中进行日志处理。
*
总结
待完善中…