• spring-retry使用介绍


    文章目录


    系列文章目录

    Springboot集成Netty

    Springboot集成Rabbitmq

    Springboot集成Retry

    springboot集成websocket

    Springboot集成Redis

    springboot整合rabbitmq使用示例


    前言

    以往我们在进行网络请求的时候,需要考虑网络异常的情况,本文就介绍了利用spring-retry框架进行网络异常重试的基础内容。


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、spring-retry是什么?

    是spring提供的一个重试框架,原本自己实现的重试机制,现在spring帮封装好提供更加好的编码体验。

    二、使用步骤

    1.引入maven库

    代码如下(示例):

    	
    	    org.springframework.retry
    	    spring-retry
    	
    	
    	    org.springframework
    	    spring-aspects
    	    4.3.9.RELEASE
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 在spring启动类上开启重试功能

    提示:添加@EnableRetry注解开启

    @SpringBootApplication
    @EnableRetry
    public class SpringRetryDemoApplication {
        public static SpringRetryAnnotationService springRetryAnnotationService;
        public static SpringRetryImperativeService springRetryImperativeService;
        public static TranditionalRetryService tranditionalRetryService;
    
        @Autowired
        public void setSpringRetryAnnotationService(SpringRetryAnnotationService springRetryAnnotationService) {
            SpringRetryDemoApplication.springRetryAnnotationService = springRetryAnnotationService;
        }
    
        @Autowired
        public void setSpringRetryImperativeService(SpringRetryImperativeService springRetryImperativeService) {
            SpringRetryDemoApplication.springRetryImperativeService = springRetryImperativeService;
        }
    
        @Autowired
        public void setTranditionalRetryService(TranditionalRetryService tranditionalRetryService) {
            SpringRetryDemoApplication.tranditionalRetryService = tranditionalRetryService;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(SpringRetryDemoApplication.class, args);
            springRetryAnnotationService.test();
            springRetryImperativeService.test();
            tranditionalRetryService.test();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    2.公共业务代码

    @Service
    @Slf4j
    public class CommonService {
        public void test(String before) {
            for (int i = 0; i < 10; i++) {
                if (i == 2) {
                    log.error("{}:有异常哦,我再试多几次看下还有没异常", before);
                    throw new RuntimeException();
                }
                log.info("{}:打印次数: {}", before, i + 1);
            }
        }
    
        public void recover(String before) {
            log.error("{}:还是有异常,程序有bug哦", before);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3. 以往的重试做法

    @Service
    @Slf4j
    public class TranditionalRetryService {
        @Autowired
        CommonService commonService;
    
        public void test() {
            // 定义重试次数以及重试时间间隔
            int retryCount = 3;
            int retryTimeInterval = 3;
            for (int r = 0; r < retryCount; r++) {
                try {
                    commonService.test("以前的做法");
                } catch (RuntimeException e) {
                    if (r == retryCount - 1) {
                        commonService.recover("以前的做法");
                        return;
                    }
                    try {
                        Thread.sleep(retryTimeInterval * 1000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
    
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    4. 使用spring-retry的命令式编码

    4.1 定义重试监听器

    提示:监听重试过程的生命周期

    @Slf4j
    public class MyRetryListener extends RetryListenerSupport {
        @Override
        public  void close(RetryContext context, RetryCallback callback, Throwable throwable) {
            log.info("监听到重试过程关闭了");
            log.info("=======================================================================");
        }
    
        @Override
        public  void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
            log.info("监听到重试过程错误了");
        }
    
        @Override
        public  boolean open(RetryContext context, RetryCallback callback) {
            log.info("=======================================================================");
            log.info("监听到重试过程开启了");
            return true;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.2 定义重试配置

    提示:配置RetryTemplate重试模板类

    @Configuration
    public class RetryConfig {
        @Bean
        public RetryTemplate retryTemplate() {
            // 定义简易重试策略,最大重试次数为3次,重试间隔为3s
            RetryTemplate retryTemplate = RetryTemplate.builder()
                    .maxAttempts(3)
                    .fixedBackoff(3000)
                    .retryOn(RuntimeException.class)
                    .build();
            retryTemplate.registerListener(new MyRetryListener());
            return retryTemplate;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4.3 命令式编码

    @Service
    @Slf4j
    public class SpringRetryImperativeService {
        @Autowired
        RetryTemplate retryTemplate;
        @Autowired
        CommonService commonService;
    
        public void test() {
            retryTemplate.execute(
                    retry -> {
                        commonService.test("命令式");
                        return null;
                    },
                    recovery -> {
                        commonService.recover("命令式");
                        return null;
                    }
            );
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5 使用spring-retry的注解式编码

    @Service
    @Slf4j
    public class SpringRetryAnnotationService {
        @Autowired
        CommonService commonService;
    
        /**
         * 如果失败,定义重试3次,重试间隔为3s,指定恢复名称,指定监听器
         */
        @Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(value = 3000L), recover = "testRecover", listeners = {"myRetryListener"})
        public void test() {
            commonService.test("注解式");
        }
    
        @Recover
        public void testRecover(RuntimeException runtimeException) {
            commonService.recover("注解式");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6 启动打印效果

    2022-05-06 11:53:12.044  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : =======================================================================
    2022-05-06 11:53:12.044  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程开启了
    2022-05-06 11:53:12.048  INFO 21812 --- [           main] c.e.s.service.CommonService              : 注解式:打印次数: 1
    2022-05-06 11:53:12.048  INFO 21812 --- [           main] c.e.s.service.CommonService              : 注解式:打印次数: 2
    2022-05-06 11:53:12.049 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 注解式:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:12.049  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程错误了
    2022-05-06 11:53:15.062  INFO 21812 --- [           main] c.e.s.service.CommonService              : 注解式:打印次数: 1
    2022-05-06 11:53:15.062  INFO 21812 --- [           main] c.e.s.service.CommonService              : 注解式:打印次数: 2
    2022-05-06 11:53:15.062 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 注解式:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:15.062  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程错误了
    2022-05-06 11:53:18.065  INFO 21812 --- [           main] c.e.s.service.CommonService              : 注解式:打印次数: 1
    2022-05-06 11:53:18.065  INFO 21812 --- [           main] c.e.s.service.CommonService              : 注解式:打印次数: 2
    2022-05-06 11:53:18.065 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 注解式:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:18.065  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程错误了
    2022-05-06 11:53:18.066 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 注解式:还是有异常,程序有bug哦
    2022-05-06 11:53:18.066  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程关闭了
    2022-05-06 11:53:18.066  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : =======================================================================
    2022-05-06 11:53:18.067  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : =======================================================================
    2022-05-06 11:53:18.067  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程开启了
    2022-05-06 11:53:18.067  INFO 21812 --- [           main] c.e.s.service.CommonService              : 命令式:打印次数: 1
    2022-05-06 11:53:18.067  INFO 21812 --- [           main] c.e.s.service.CommonService              : 命令式:打印次数: 2
    2022-05-06 11:53:18.067 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 命令式:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:18.067  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程错误了
    2022-05-06 11:53:21.079  INFO 21812 --- [           main] c.e.s.service.CommonService              : 命令式:打印次数: 1
    2022-05-06 11:53:21.079  INFO 21812 --- [           main] c.e.s.service.CommonService              : 命令式:打印次数: 2
    2022-05-06 11:53:21.079 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 命令式:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:21.079  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程错误了
    2022-05-06 11:53:24.082  INFO 21812 --- [           main] c.e.s.service.CommonService              : 命令式:打印次数: 1
    2022-05-06 11:53:24.082  INFO 21812 --- [           main] c.e.s.service.CommonService              : 命令式:打印次数: 2
    2022-05-06 11:53:24.082 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 命令式:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:24.082  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程错误了
    2022-05-06 11:53:24.082 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 命令式:还是有异常,程序有bug哦
    2022-05-06 11:53:24.082  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : 监听到重试过程关闭了
    2022-05-06 11:53:24.082  INFO 21812 --- [           main] c.e.s.listener.MyRetryListener           : =======================================================================
    2022-05-06 11:53:24.082  INFO 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:打印次数: 1
    2022-05-06 11:53:24.083  INFO 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:打印次数: 2
    2022-05-06 11:53:24.083 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:27.084  INFO 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:打印次数: 1
    2022-05-06 11:53:27.084  INFO 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:打印次数: 2
    2022-05-06 11:53:27.084 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:30.090  INFO 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:打印次数: 1
    2022-05-06 11:53:30.090  INFO 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:打印次数: 2
    2022-05-06 11:53:30.090 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:有异常哦,我再试多几次看下还有没异常
    2022-05-06 11:53:30.090 ERROR 21812 --- [           main] c.e.s.service.CommonService              : 以前的做法:还是有异常,程序有bug哦
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    三、总结

    本文仅仅简单介绍了spring-retry的基本使用,相较于以往的做法,个人认为注解式更为简便,命令式看个人喜好,更多使用方法参照github主页

    https://github.com/spring-projects/spring-retry

    四、示例源码

    https://gitee.com/teajoy/springboot-modules/tree/master/springboot-retry

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    Linux备份策略:保证数据安全
    时序预测 | MATLAB实现POA-CNN-GRU鹈鹕算法优化卷积门控循环单元时间序列预测
    Ansible之Playbook的任务控制
    华纳云:mysql无法添加或更新子行如何解决
    基于WebSocket的modbus通信(二)- 客户端
    最详细的CompletableFuture异步编程-进阶篇
    html总结-1-结构与常见标签
    spring+pom-注意多重依赖时的兼容问题[java.lang.NoSuchMethodError]
    《软件质量保证与测试》第 7 章——验收测试 重点部分总结
    Windows 与linux 账户密码的破解
  • 原文地址:https://blog.csdn.net/sebeefe/article/details/126114196