欢迎来到我的博客

spring-retry自定义失败重试简单demo

依赖引入

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

RetryConfig.java

package com.xxx.config.retry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

@Configuration
public class RetryConfig {

    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    @Bean
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();

        // 设置最大重试次数(包括第一次尝试共6次)
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(6);
        retryTemplate.setRetryPolicy(retryPolicy);

        // 设置自定义退避策略
        retryTemplate.setBackOffPolicy(new CustomBackOffPolicy());

        // 添加重试监听器,用于记录重试过程
        retryTemplate.registerListener(new RetryListener() {
            @Override
            public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
                return true;
            }

            @Override
            public <T, E extends Throwable> void close(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                if (throwable != null) {
                    log.info("所有重试尝试完成,最终失败");
                } else {
                    log.info("重试成功,总尝试次数: {}", context.getRetryCount());
                }
            }

            @Override
            public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                log.info("第{}次推送失败,准备重试...", context.getRetryCount());
            }
        });

        return retryTemplate;
    }
}

CustomBackOffPolicy.java

package com.xxx.config.retry;

import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.RetryContext;
import org.springframework.retry.backoff.BackOffContext;
import org.springframework.retry.backoff.BackOffPolicy;

public class CustomBackOffPolicy implements BackOffPolicy {

    protected final Logger log = LoggerFactory.getLogger(this.getClass());

    // 重试间隔时间,单位:毫秒 (5s, 10s, 30s, 1min, 5min)
    private final long[] intervals = {5000, 10000, 30000, 60000, 300000};

    @Override
    public BackOffContext start(RetryContext context) {
        // 创建并返回一个上下文对象,用于跟踪重试次数
        return new SimpleBackOffContext();
    }

    @SneakyThrows
    @Override
    public void backOff(BackOffContext backOffContext) {
        // 转换上下文对象类型
        SimpleBackOffContext context = (SimpleBackOffContext) backOffContext;

        // 获取当前重试次数(从0开始计数)
        int retryCount = context.getRetryCount();

        // 根据重试次数获取对应的间隔时间,如果超出范围则使用最后一个间隔
        long interval = retryCount < intervals.length ? intervals[retryCount] : intervals[intervals.length - 1];

        log.info("等待{}秒后进行第{}次重试...", interval / 1000, retryCount + 1);

        // 线程休眠指定时间
        Thread.sleep(interval);

        // 更新重试次数
        context.incrementRetryCount();
    }

    /**
     * 简单的上下文类,用于跟踪重试次数
     */
    private static class SimpleBackOffContext implements BackOffContext {
        private int retryCount = 0;

        public int getRetryCount() {
            return retryCount;
        }

        public void incrementRetryCount() {
            this.retryCount++;
        }
    }

}


MessageSender.java

package com.xxx.config.retry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;

@Component
public class MessageSender {

    @Autowired
    private RetryTemplate retryTemplate;

    /**
     * 带重试机制的消息发送方法
     */
    public void sendMessage(String message) {
        try {
            retryTemplate.execute(context -> {
                // 执行实际发送操作
                boolean success = doSend(message);
                if (!success) {
                    throw new RuntimeException("消息发送失败");
                }
                return true;
            });
        } catch (Exception e) {
            System.err.println("最终发送失败: " + e.getMessage());
        }
    }

    /**
     * 实际发送消息的方法
     */
    private boolean doSend(String message) {
        // 这里是实际发送逻辑,当前模拟发送失败
        System.out.println("正在发送消息: " + message);
        return false; // 模拟失败,实际应用中根据发送结果返回
    }


}

posted @ 2025-07-25 16:08  fchhk  阅读(16)  评论(0)    收藏  举报