分享免费的编程资源和教程

网站首页 > 技术教程 正文

SpringBoot-整合Retry框架-RetryTemplate实现重试机制(二)

goqiw 2024-09-25 20:13:16 技术教程 61 ℃ 0 评论

Retry框架介绍

Retry重试框架,支持AOP切入的方式使用,支持注解;重试次数、重试延迟、重试触发条件、重试的回调方法等功能来实现重试机制。

项目中我们可以通过两种不同的方式使用Spring Retry重试功能,一种是@Retryable注解的方式,另一种是RetryTemplate方式。

springboot整合RetryTemplate实现重试

配置RetryTemplate

首先配置RetryTemplate并注册为Java Bean交有Spring管理

@EnableRetry
@SpringBootApplication
@MapperScan("com.qingfeng.*.mapper")
@EnableMyRedis
@EnableMyProtect
@ServletComponentScan
//@ServletComponentScan("com.qingfeng.framework.servlet")
public class QingfengApplication {

    @Value("${spring.application.name}")
    private  String application;

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

    @Bean
    MeterRegistryCustomizer<MeterRegistry> configurer() {
        return (registry) -> registry.config().commonTags("application", application);
    }


    @Bean
    public RetryTemplate retryTemplate() {
        /**
         * The RetryPolicy determines when an operation should be retried.
         * A SimpleRetryPolicy is used to retry a fixed number of times. On the other hand, the BackOffPolicy is used to control backoff between retry attempts.
         * Finally, a FixedBackOffPolicy pauses for a fixed period of time before continuing.
         */
        RetryTemplate retryTemplate = new RetryTemplate();

        FixedBackOffPolicy fixedBackOffPolicy = new FixedBackOffPolicy();
        fixedBackOffPolicy.setBackOffPeriod(2000l);
        retryTemplate.setBackOffPolicy(fixedBackOffPolicy);

        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(2);
        retryTemplate.setRetryPolicy(retryPolicy);

        retryTemplate.registerListener(new AppRetryListenerSupport());

        return retryTemplate;
    }
}

1、setBackOffPeriod设置重试间隔2秒。

2、setMaxAttempts设置最大重试次数2次。

3、registerListener注册retryTemplate监听器。

创建监听器AppRetryListenerSupport

实现监听器AppRetryListenerSupport,当重试的时候提供不同触发事件的回调方法,在回调中可以针对不同的触发事件进行处理。

package com.qingfeng.framework.retry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.listener.RetryListenerSupport;

/**
 * @author Administrator
 * @version 1.0.0
 * @ProjectName qingfeng
 * @Description TODO
 * @createTime 2022年04月28日 20:54:00
 */
public class AppRetryListenerSupport extends RetryListenerSupport {

    private static final Logger LOGGER = LoggerFactory.getLogger(AppRetryListenerSupport.class);


    @Override
    public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        LOGGER.info("The retry is closed.");
        System.out.println("The retry is closed.");
        super.close(context, callback, throwable);
    }

    @Override
    public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
        LOGGER.info("The retry is on error.");
        System.out.println("The retry is on error.");
        // 重试的时候如果需要处理一些其他逻辑,可以在该方法内增加
        super.onError(context, callback, throwable);
    }

    @Override
    public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
        LOGGER.info("The retry is open.");
        System.out.println("The retry is open.");
        return super.open(context, callback);
    }
}

测试retryTemplate.execute()

使用retryTemplate.execute() 调用需要需要自动重试的方法。

    @Autowired
    private RetryTemplate retryTemplate;    

    @GetMapping("/retryTemplateTest")
    public Object retryTemplateTest(@RequestParam int num) throws Exception {
        try {
            Object result = retryTemplate.execute(arg -> testService.getRetryTemplateNum(num));
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

重启项目,然后在浏览器中输入:

http://localhost:8090/common/test/retryTemplateTest?num=0

Retry问题分析

由于retry用到了aspect增强,所以会有aspect的坑,就是方法内部调用,会使aspect增强失效,那么retry当然也会失效。

public class demo {
    public void A() {
        B();
    }
    //这里B不会执行
    @Retryable(Exception.class)
    public void B() {
        throw new RuntimeException("retry...");
    }
}

重试机制,不能在接口实现类里面写。所以要做重试,必须单独写个service。
maxAttemps参数解释的是说重试次数,测试的时候发现这个=1时,方法一共只执行了一次,=3时,一共只执行3次。

若有收获,就点个赞吧

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表