首页后端开发其他后端知识spring-retry是什么,方法请求重试怎样用

spring-retry是什么,方法请求重试怎样用

时间2024-03-24 10:46:03发布访客分类其他后端知识浏览413
导读:这篇文章给大家分享的是“spring-retry是什么,方法请求重试怎样用”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“spring-retry是什么,方法请求重试...
这篇文章给大家分享的是“spring-retry是什么,方法请求重试怎样用”,文中的讲解内容简单清晰,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下“spring-retry是什么,方法请求重试怎样用”吧。

1 spring-retry是什么?

以往我们在进行网络请求的时候,需要考虑网络异常的情况,本文就介绍了利用spring-retry,是spring提供的一个重试框架,原本自己实现的重试机制,现在spring帮封装好提供更加好的编码体验。

2 使用步骤

2.1 引入maven库

代码如下(示例):

	dependency>
    
	    groupId>
    org.springframework.retry/groupId>
    
	    artifactId>
    spring-retry/artifactId>
    
	/dependency>
    
	dependency>
    
	    groupId>
    org.springframework/groupId>
    
	    artifactId>
    spring-aspects/artifactId>
    
	    version>
    4.3.9.RELEASE/version>
    
	/dependency>

2.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();

    }

}

2.3 公共业务代码

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

    }

}

2.4 传统的重试做法

@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();

                }

            }


        }


    }

}

2.5 使用spring-retry的命令式编码

2.5.1 定义重试监听器

提示:监听重试过程的生命周期
@Slf4j
public class MyRetryListener extends RetryListenerSupport {
    
    @Override
    public T, E extends Throwable>
     void close(RetryContext context, RetryCallbackT, E>
 callback, Throwable throwable) {
    
        log.info("监听到重试过程关闭了");
    
        log.info("=======================================================================");

    }
    

    @Override
    public T, E extends Throwable>
     void onError(RetryContext context, RetryCallbackT, E>
 callback, Throwable throwable) {
    
        log.info("监听到重试过程错误了");

    }
    

    @Override
    public T, E extends Throwable>
     boolean open(RetryContext context, RetryCallbackT, E>
 callback) {
    
        log.info("=======================================================================");
    
        log.info("监听到重试过程开启了");
    
        return true;

    }

}

2.5.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;

    }

}

2.5.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;

                }
    
        );

    }

}

2.6使用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("注解式");

    }

}

3 SpringBoot整合spring-retry

我们使用SpringBoot来整合spring-retry组件实现重试机制。

3.1 添加@EnableRetry注解

在主启动类Application上添加@EnableRetry注解,实现对重试机制的支持

@SpringBootApplication
@EnableRetry
public class RetryApplication {

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

    }

 
}

注意:@EnableRetry也可以使用在配置类、ServiceImpl类、方法上

3.2 接口实现

注意:接口类一定不能少,在接口类中定义你需要实现重试的方法,否则可能会无法实现重试功能

我的测试接口类如下:

public interface RetryService {
        public String testRetry()  throws Exception;
}

3.3 添加@Retryable注解

我们针对需要实现重试的方法上添加@Retryable注解,使该方法可以实现重试,这里我列出ServiceImpl中的一个方法:

@Service
public class RetryServiceImpl implements RetryService {

    @Override
    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
    public String testRetry() throws Exception {
    
 
        System.out.println("开始执行代码:"+ LocalTime.now());
    
        int code = 0;

        // 模拟一直失败
        if(code == 0){
    
           // 这里可以使自定义异常,@Retryable中value需与其一致
            throw new Exception("代码执行异常");

        }
    
        System.out.println("代码执行成功");
    
        return "success";

    }

}

说明:@Retryable配置元数据情况:
value :针对指定抛出的异常类型,进行重试,这里指定的是Exception
maxAttempts :配置最大重试次数,这里配置为3次(包含第一次和最后一次)
delay: 第一次重试延迟间隔,这里配置的是2s
multiplier :每次重试时间间隔是前一次几倍,这里是1.5倍

3.4 Controller测试代码

@RestController
@RequestMapping("/test")
public class TestController {
    
    //  一定要注入接口,通过接口去调用方法
    @Autowired
    private RetryService retryService;

 
    @GetMapping("/retry")
    public String testRetry() throws Exception {
    
        return retryService.testRetry();

    }

}

3.5 发送请求

发送请求后,我们发现后台打印情况,确实重试了3次,并且在最后一次重试失败的情况下,才抛出异常,具体如下(可以注意下时间间隔)

3.6 补充:@Recover

一般情况下,我们重试最大设置的次数后,仍然失败抛出异常,我们会通过全局异常处理类进行统一处理,但是我们其实也可以自行处理,可以通过@Recover注解来实现,具体如下:

@Service
public class RetryServiceImpl implements RetryService {

 
    @Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
    public String testRetry() throws Exception {
    
 
        System.out.println("开始执行代码:"+ LocalTime.now());
    
        int code = 0;

        if(code == 0){
    
            // 这里可以使自定义异常,@Retryable中value需与其一致
            throw new Exception("代码执行异常");

        }
    
        System.out.println("代码执行成功");
    
        return "success";

    }

 
    /**
     * 最终重试失败处理
     * @param e
     * @return
     */
    @Recover
    public String recover(Exception e){
    
 
        System.out.println("代码执行重试后依旧失败");
    
        return "fail";

    }

}
    

注意:
1)@Recover的方法中的参数异常类型需要与重试方法中一致
2)该方法的返回值类型与重试方法保持一致

再次测试如下(发现不会再抛出异常)



感谢各位的阅读,以上就是“spring-retry是什么,方法请求重试怎样用”的内容了,通过以上内容的阐述,相信大家对spring-retry是什么,方法请求重试怎样用已经有了进一步的了解,如果想要了解更多相关的内容,欢迎关注网络,网络将为大家推送更多相关知识点的文章。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: spring-retry是什么,方法请求重试怎样用
本文地址: https://pptw.com/jishu/652008.html
如何保留两位小数,php怎么写 php中字符串怎么去掉“-”字符,可以用哪些方法

游客 回复需填写必要信息