看头图说话
前言:当我们调用第三方接口或者在同一个注册中心的其他服务的时候,由于一些原因没有返回成功的标识,需要尝试多次获取响应。
加入依赖
<dependency>
<groupId>org.springframework.retrygroupId>
<artifactId>spring-retryartifactId>
dependency>
手写代码实现
public class TestJob {
private static Logger logger = LoggerFactory.getLogger(TestJob.class);
private int cnt = 0;
public void retry(String params){
RetryTemplate oRetryTemplate = new RetryTemplate();
// SimpleRetryPolicy oRetryPolicy = new SimpleRetryPolicy(5);//简单重试策略,重试5次
AlwaysRetryPolicy oRetryPolicy = new AlwaysRetryPolicy();//重试策略,一直重试直到成功
oRetryTemplate.setRetryPolicy(oRetryPolicy);//指定重试策略,也可以用其他的
try {
// obj为doWithRetry的返回结果,可以为任意类型
Object obj = oRetryTemplate.execute(new RetryCallback
@Override
public Object doWithRetry(RetryContext context) throws Exception {// 开始重试
System.out.println(params + "----retry----" + context.getRetryCount());
doTask(params);
return "success";
}
}, new RecoveryCallback
@Override
public Object recover(RetryContext context) throws Exception { // 重试多次后都失败了
System.out.println("重试多次失败");
return "error";
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void doTask(String data) throws Exception {
try{
System.out.println("exec---" + data);
if(cnt==10){
System.out.println("exec success");
return;
}
int code = 400;
if(code!=200){
cnt++;
throw new Exception("error"); // 抛出异常,执行重试
}
}catch (Exception e){
System.out.println(e.getMessage());
throw e;
}
}
public static void main(String[] args) {
TestJob t = new TestJob();
System.out.println("start exec");
String data = UUID.randomUUID().toString();
try{
t.doTask(data);
}catch (Exception e){
//重试data
t.retry(data);
}
}
}
基于注解实现
value//开启重试注解,必须
public class CallServiceImpl {
MyService myService;
RedisService redisService;
private static Logger logger= LoggerFactory.getLogger(CallServiceImpl.class);
//重试注解,必须
2, backoff = (delay = 2000L)) (value = {Exception.class}, maxAttempts =
public Result invoke(MyParamForm param) throws Exception {
Result,Object>> result = new Result<>();
try{
result=myService.invoke(param);
}catch (Exception e){
logger.error("invoke err:{}, param:{}",e.getMessage(),JSON.toJSONString(esgParamForm));
throw e;
}
if (result.getCode() != ResultCodeEnum.SUCCESS.getCode()){
logger.error("invoke fail:{}, param:{}",
JSON.toJSONString(result),JSON.toJSONString(esgParamForm));
throw new Exception("invoke callfail");
}
return result;
}
}
抛出指定异常才会重试
maxAttempts最大重试次数,默认3次
backoff重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L;multiplier(指定延迟倍数)
最后,关于重试还有@Recover注解,注解在方法上,重试失败后会执行该方法,@Retryable注解也还有其他一些值没有说到,朋友需自行探究,欢迎留言相告。
评论