使用Spring RetryTemplate优雅的进行重试

1、使用场景

  • 在我们与下游通过http进行数据交互时,会约定接口协议,比如:双方约定返回20000时,可以重新请求获取正确的结果。
  • 在进行http进行网络通信时,经常会发生一些网络层面的异常如:IOException:unexpected end of stream on Connection;SocketException:Broken pipe (Write failed)、Connection reset等,比较懒的做法是加上重试逻辑,如果你是技术宅,可以深究里面的深层原因。
  • 其它任何可以重试的场景

2、常规的重试写法

    int retryTimes = 3;
    for (int i = 0; i < retryTimes; i++) {
        Result result = doSomethingPre();
        if (result == 预期值){
            doSomething();
            berak;
        }
    }

有没有觉得这段代码就像一坨shit,如果这种重试需求很多,那么打开项目就会有满屏shit。做为一个有追求的码农,不能容忍这种事情发生,接下来Spring RetryTemplate闪亮登场。

3、Spring RetryTemplate的使用

  • 引入依赖
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.4.RELEASE</version>
</dependency>
  • 配置
    既要重试,我们肯定要定义好重试的策略:重试的触发条件,重试次数,时间间隔等要素。

RetryPolicy


下图是RetryPolicy及实现类的关系图,太大了,看不清,没关系,我们只看最简单最常用的SimpleRetryPolicy,它里面可以设置重试次数:setMaxAttempts();不设置的话,默认值是3次。

BackOffPolicy

顾名思义BackOffPolicy是退避策略,看一下他的实现类。

用ExponentialBackOffPolicy来举例子,它是指数退避策略,需设置参数
initialInterval:初始休眠时间,默认100毫秒
multiplier:指定乘数,当前休眠时间*multiplier即为下一次的休眠时间;
maxInterval:指定最大休眠时间,默认30秒,避免multiplier过大引起无限期等待。

RetryTemplate

spring容器中注入RetryTemplate这个bean,并在该bean中设置上述两个策略:

    @Bean
    public RetryTemplate simpleRetryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        retryTemplate.setRetryPolicy(new SimpleRetryPolicy());
        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
        backOffPolicy.setInitialInterval(3000);
        backOffPolicy.setMultiplier(2);
        backOffPolicy.setMaxInterval(15000);
        retryTemplate.setBackOffPolicy(backOffPolicy);
        return retryTemplate;
    }

上面的配置通俗的说就是,最大重试三次,时间间隔为3,32,32*2,且时间间隔不大于15s。

  • 使用
    retryTemplate.execute(RetryCallback<T, E> retryCallback);
    RetryCallback接口只有一个接口,即为函数式接口,可以使用lamda表达式来写,简洁且直观。
    最终写法:retryTemplate.execute(retryContext -> {重试逻辑代码});
    这段为源代码,可以省略,可以看到最终调用为RetryCallback接口的实现类,及lamda表达式
    @Override
    public final <T, E extends Throwable> T execute(RetryCallback<T, E> retryCallback) throws E {
	return doExecute(retryCallback, null, null);
    }

    protected <T, E extends Throwable> T doExecute(RetryCallback<T, E> retryCallback,RecoveryCallback<T> recoveryCallback, RetryState state)throws E, ExhaustedRetryException {
        ......
        return retryCallback.doWithRetry(context);
    }

上述是retryTemplate最简单的用法,它还有很多很强大的用法,有时间再来补充。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring基于Redis的重试框架是一种用于处理失败任务的解决方案。当执行某个任务时,如果发生错误或失败,我们可以使用Spring框架提供的Redis作为存储机制,记录失败任务的相关信息,并在后续进行重试。 该框架的实现主要有以下几个步骤: 1. 配置Redis:首先我们需要在Spring配置文件中配置Redis作为数据存储。我们可以使用Spring提供的RedisTemplate类来简化Redis的操作,例如存储、读取数据等。 2. 记录失败任务:当任务执行失败时,我们可以将任务的相关信息(例如任务ID、参数等)存储到Redis中。这样就可以确保即使应用程序重启或中断,失败任务的信息仍然可以被保留下来。 3. 定时重试:通过配置定时任务,我们可以定期检查Redis中失败任务的信息,并进行重试操作。在每一次定时任务的执行过程中,我们可以从Redis中读取失败任务的信息,并将其重新提交给任务执行器进行重试。 4. 限制重试次数:为了避免任务反复失败而导致无限重试,我们可以根据需求来设置任务的重试次数。当任务达到了最大重试次数后,我们可以将其从Redis中移除,避免任务的无限循环重试。 总之,Spring基于Redis的重试框架提供了一种可靠的机制来处理失败任务。通过使用Redis作为数据存储,我们可以保证失败任务的信息持久化,并通过定时任务实现重试操作。这样可以提高任务的可靠性,并减少因为任务执行失败而导致的业务影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值