• 重试机制-spring-retry、guava-retry


    重试机制是什么?

    网络重试机制是用于在网络通信中处理失败的请求。接口重试可以在一定的时间间隔内多次尝试发送相同的请求,直到请求成功或达到最大重试次数为止。

    为什么要重试?

    1. 提高请求的成功率:网络通信中可能会出现各种问题,如网络延迟、连接超时、服务器错误等。通过接口重试机制,可以尝试多次发送请求,增加请求成功的可能性。

    2. 处理瞬时故障:有时候,请求失败是由于短暂的网络故障或服务器负载过高等瞬时问题引起的。通过接口重试,可以在稍后的尝试中成功发送请求,而无需手动干预。

    3. 自动化处理:接口重试可以自动处理请求失败的情况,无需手动干预。这样可以减少开发人员的工作量,并提高系统的稳定性和可靠性。

    注意:接口重试并不是万能的解决方案,有时候请求失败可能是由于永久性的问题,如无效的请求参数或者权限不足等。在设计接口重试机制时,需要考虑到这些情况,并设置合理的重试策略和最大重试次数。

    重试的场景有哪些?

    网络不稳定导致请求失败;

    服务端繁忙,导致响应时间过长;

    服务端出现故障,导致请求失败;

    传参错误等错误,导致请求失败;

    第三方接口调用失败,例如:钉钉、微信、权限等。

    如何进行重试?

    ①、固定次数重试

    设置一个固定的重试次数,在每次请求失败时都重新发送请求,直到达到最大重试次数或请求成功为止。

    ②、spring-retry

    spring提供的请求重试组件,根据配置的重试策略进行重试

    1. <dependency>
    2. <groupId>org.springframework.retry</groupId>
    3. <artifactId>spring-retry</artifactId>
    4. </dependency>

    开启重试功能:

    在启动类或者配置类上添加 @EnableRetry 注解

    在需要重试的方法上添加 @Retryable 注解:标志当前方法使用重试机制

    @Backoff:等待多久开始重试(指定重试的次数、时间间隔)

    默认重试次数是3次,重试间隔是1s

    @Retryable(maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 2))

    @Recover:当重试达到指定次数之后,会调用指定的方法来进行日志记录等操作

    1. @Recover
    2. public void recover(RuntimeException e){
    3. System.out.println("达到最大重试次数"+e);
    4. }

    注意:@Recover 注解标记的方法必须和被 @Retryable 标记的方法在同一个类中

    代码演示:

    1. @Service
    2. public class SpringRetryServiceImpl {
    3. @Autowired
    4. private LoginServiceImpl loginService;
    5. @Retryable(maxAttempts = 3,backoff = @Backoff(delay = 2000,multiplier = 2))
    6. public String getUserInfo(String id) throws Exception {
    7. System.out.println("开始时间"+System.currentTimeMillis());
    8. JSONObject bodyJson = loginService.getUserService(id);
    9. if (!bodyJson.get("code").equals(200)) {
    10. throw new Exception("失败");
    11. }
    12. return "调用成功";
    13. }
    14. @Recover
    15. public void recover(Exception e){
    16. System.out.println("达到最大重试次数"+e);
    17. }
    18. }

     ③、guava-retry

    能够根据 返回值 来判断是否需要重试

    1. @Service
    2. public class GuavaImpl {
    3. @Autowired
    4. private LoginServiceImpl loginService;
    5. public String getUserInfo(String id) throws Exception {
    6. Callable<String> task = new Callable<String>() {
    7. @Override
    8. public String call() throws Exception {
    9. JSONObject bodyJson = loginService.getUserService(id);
    10. if (!bodyJson.get("code").equals(200)) {
    11. throw new Exception("失败");
    12. }
    13. return "调用成功";
    14. }
    15. };
    16. Retryer<String> retryer = RetryerBuilder.<String>newBuilder()
    17. //无论出现什么异常,都进行重试
    18. .retryIfException()
    19. //返回结果为 error时,进行重试
    20. .retryIfResult(result -> Objects.equals(result, "error"))
    21. //重试等待策略:等待 2s 后再进行重试
    22. .withWaitStrategy(WaitStrategies.fixedWait(2, TimeUnit.SECONDS))
    23. //重试停止策略:重试达到 3
    24. .withStopStrategy(StopStrategies.stopAfterAttempt(3))
    25. .withRetryListener(new RetryListener() {
    26. @Override
    27. public <V> void onRetry(Attempt<V> attempt) {
    28. System.out.println("RetryListener: 第" + attempt.getAttemptNumber() + "次调用");
    29. }
    30. })
    31. .build();
    32. try {
    33. retryer.call(task);
    34. } catch (Exception e) {
    35. e.printStackTrace();
    36. }
    37. return "调用成功";
    38. }
    39. }

    超时:服务不要一直在服务端进行堆积(影响新请求处理/系统崩溃),请求超过设置时间没有被处理就取消或抛异常

    重试:和超时绑定,多次发送相同

  • 相关阅读:
    C#:实现蚁群优化算法(附完整源码)
    一台电脑如何登录多个抖音小店(抖音小店怎么关联多个账号)
    一次赌博-誉天RHCA学员学习分享
    2024普通人怎么赚钱?2024普通人做什么行业赚钱?2024普通人最有前景的项目!2024普通人怎么搞钱?
    没有基础能否学Java
    类与对象(上篇)
    【设计模式】设计模式
    泛型的约束不止一面
    M4Singer Ubuntu 4060ti16G 笔记【2】
    开源交流丨任务or实例 详解大数据DAG调度系统Taier任务调度
  • 原文地址:https://blog.csdn.net/weixin_43319713/article/details/132848822