看头图说话

A小天

共 3270字,需浏览 7分钟

 ·

2020-12-17 12:41

a713a8d8a8ec92ae3f4e9335afc2b06a.webp


前言:当我们调用第三方接口或者在同一个注册中心的其他服务的时候,由于一些原因没有返回成功的标识,需要尝试多次获取响应。


01
加入依赖


<dependency>         <groupId>org.springframework.retrygroupId>         <artifactId>spring-retryartifactId>dependency>


02
手写代码实现


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); } }}


03
基于注解实现


@Service@EnableRetry //开启重试注解,必须public class CallServiceImpl {    @Autowired    MyService myService;
@Autowired RedisService redisService;
private static Logger logger= LoggerFactory.getLogger(CallServiceImpl.class);
@Override    //重试注解,必须 @Retryable(value = {Exception.class}, maxAttempts = 2, backoff = @Backoff(delay = 2000L)) public Result invoke(MyParamForm param) throws Exception { ResultString,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;    }}
value

抛出指定异常才会重试

maxAttempts

最大重试次数,默认3次

backoff

重试等待策略,默认使用@Backoff,@Backoff的value默认为1000L;multiplier(指定延迟倍数)


最后,关于重试还有@Recover注解,注解在方法上,重试失败后会执行该方法,@Retryable注解也还有其他一些值没有说到,朋友需自行探究,欢迎留言相告。


e8f619806bb04d33b6096c7f55a4c399.webp
浏览 20
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报