程序员不能不懂的Retry机制

13 篇文章 1 订阅
7 篇文章 0 订阅

Retry重试机制

当我们调用一个接口时, 可能由于网络等原因造成第一次失败, 再去尝试就成功了, 这就是重试机制.

重试的解决方案有很多, 比如利用 try-catch-redo简单重试模式, 通过判断返回结果或监听异常来

判断是否重试, 具体可以看如下例子:

public void testRetry(){
        boolean result = false;
        try{
            result = load();
            if (!result){
                load(); //一次重试
            }
        }catch (Exception e){
            load(); //一次重试
        }
    }

但是这种策略有个问题就是: 正常逻辑和重试逻辑强耦合. 基于这个问题, 我们可以使用 Spring-Retry工具,

该工具把重试操作模板定制化, 可以设置重试策略和回退策略. 同时 重试执行实例保证线程安全.

Retry重试机制的使用

首先在pom.xml中引入所需的依赖:

        <dependency>
            <groupId>org.springframework.retry</groupId>
            <artifactId>spring-retry</artifactId>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

添加完依赖后, 需要在入口类Application中添加注解@EnableRetry开启retry重试:

@SpringBootApplication
@EnableRetry
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

然后我们新建个接口RetryService:

/**
 * @Author wuwei
 * @Date 2019/12/8 8:22 下午
 */
public interface RetryService {
    AyMood findByIdRetry(String id);
}

接着创建实现类RetryServiceImpl:

/**
 * @Author wuwei
 * @Date 2019/12/8 8:22 下午
 */
@Service
public class RetryServiceImpl implements AyMoodService {
    
    @Override
    @Retryable(value = {BusinessException.class}, maxAttempts = 5,
    backoff = @Backoff(delay = 5000, multiplier = 2))
    public AyMood findByIdRetry(String id) {
        System.out.println("[findByIdRetry]方法重试失败了!!!");
        throw new BusinessException("retry");
    }

}

我们在方法中故意抛出自定义异常BusinessException,

关于自定义处理全局异常,请移步: https://blog.csdn.net/dummyo/article/details/103450968

@Retryable:

  • value属性表示当出现哪些异常的时候触发重试
  • maxAttemps: 表示最大重试次数, 默认为3
  • delay表示重试的延迟时间
  • multiplier表示第n次重试是n-1次重试的多少倍.[例子中: 失败后第一次过5秒后重试, 第二次过10秒, 20秒]

我们写个测试方法来调用上述方法:

/**
 * @Author wuwei
 * @Date 2019/12/8 10:24 下午
 */
@RestController
@RequestMapping("/start")
public class TestController {
    
    @Autowired
    AyMoodService ayMoodService;
    
    @RequestMapping("/retry")
    public String findByIdRetry(){
        AyMood ayMood = ayMoodService.findByIdRetry("1");
        return "";
    }
}

然后在浏览器中请求这个接口, 会发现控制台一直在进行重试, 5次后就返回结果.

Over

如果觉得需要更多技术干货, 来我的CSDN 和 GitHub哦

CSDN: https://println.tk/

Github: https://github.com/uweii

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值