@RabbitListener处理重试机制完成后的异常捕获

  • application.properties中配置开启手动签收
java 复制代码
spring.rabbitmq.listener.direct.acknowledge-mode=manual
spring.rabbitmq.listener.simple.acknowledge-mode=manual
  • 定义一个重试器
java 复制代码
@Slf4j
@Configuration
public class RabbitMQRetryConfing {

    @Bean("customRetry")
    public RetryTemplate retryTemplate() {
        RetryTemplate retryTemplate = new RetryTemplate();
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
        retryPolicy.setMaxAttempts(3); // 设置重试次数
        retryTemplate.setRetryPolicy(retryPolicy);

        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(2000); // 重试间隔,单位:毫秒
        retryTemplate.setBackOffPolicy(backOffPolicy);

        // 添加 RetryListener 以观察重试过程
        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) {
            }

            @Override
            public <T, E extends Throwable> void onError(RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
                //春姐,这里可以灵活配置重试失败后的回调,例如发送告警、更新数据库状态等
                if (context.getRetryCount() >= retryPolicy.getMaxAttempts()) {
                    int retryCount = context.getRetryCount();
                    // 当重试次数耗尽时进行处理
                    log.info("已达到最大重试次数{}次,丢弃本次任务",retryCount);
                }
            }
        });

        return retryTemplate;
    }
}

这个重试器可以配置最大重试次数、重试之间间隔次数等策略配置,调用重试器的execute方法可以进行队列消费,如果在执行一次任务期间发生了异常,则会根据配置的重试次数以及间隔时间自动触发下一次重试,每一次重试都是在同一个线程中执行完成的,并且RetryTemplate会为每一次重试失败进行回调,提供了诸如 onOpen、onClose、onError等回调时机。

  • RabbitMQ监听器回调方法
java 复制代码
	@Autowired
    @Qualifier("customRetry")
    private RetryTemplate retryTemplate;

    //queues消费的队列  ackMode确认模式 MANUAL 手动确认
    @RabbitListener(queues = "q",ackMode = "MANUAL")
    @Override
    public void onMessage(Message message, Channel channel)   {
        try {
            retryTemplate.execute(new RetryCallback<Object, Throwable>() {
                @Override
                public Object doWithRetry(RetryContext retryContext) throws Throwable {
                    // 消息的唯一标识id
                    long deliveryTag = message.getMessageProperties().getDeliveryTag();
                    log.info("接收到mq信息" + new String(message.getBody()));
                    try{
                        //todo 开始业务处理
                        String msg = new String(message.getBody());
                        Integer articleId = Integer.parseInt(msg);
                        newsService.pullNews(articleId);
                        // 手动签收的第一个参数为消息的唯一标识id、第二个参数表示是否批量签收
                        channel.basicAck(deliveryTag,false);
                        log.info("消费mq消息成功,articleId为:{}",articleId);
                        return null;
                    }catch (Throwable e){
                        log.error(String.format("失败,异常信息为:%s",new String(message.getBody()),e.getMessage()));
                        //重新抛出异常  触发重试机制
                        throw e;
                    }
                    finally {
                        //重试次数达到限制
                        log.error(String.format("失败",new String(message.getBody())));
                        //不重新入队,发送到死信队列
                        // 手动拒绝签收的第一个参数为消息id、
                        // 第二个参数表示是否批量签收
                        // 第三个参数消息是否重回队列
                        channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
                    }
                }
            });
        } catch (Throwable throwable) {
            log.info("执行回调重试上下文出现异常");
        }

    }

这样,当耗尽完重试次数之后就会被回调到onError方法中执行自定义的异常逻辑处理。

相关推荐
万粉变现经纪人1 小时前
如何解决 pip install llama-cpp-python 报错 未安装 CMake/Ninja 或 CPU 不支持 AVX 问题
开发语言·python·开源·aigc·pip·ai写作·llama
小码哥_常1 小时前
Spring Boot:别再重复造轮子,这些内置功能香麻了
后端
清风明月一壶酒2 小时前
OpenClaw自动处理Word文档全流程
开发语言·c#·word
其实防守也摸鱼2 小时前
CTF密码学综合教学指南--第五章
开发语言·网络·笔记·python·安全·网络安全·密码学
皮皮林5512 小时前
OpenFeign 首次调用卡 3 秒?八年老开发扒透 5 个坑,实战优化到 100ms!
后端
小郑加油3 小时前
python学习Day12:pandas安装与实际运用
开发语言·python·学习
AC赳赳老秦3 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
KuaCpp3 小时前
C++面向对象(速过复习版)
开发语言·c++
千寻girling3 小时前
《 Git 详细教程 》
前端·后端·面试
wbs_scy3 小时前
Linux线程同步与互斥(三):线程同步深度解析之POSIX 信号量与环形队列生产者消费者模型,从原理到源码彻底吃透
java·开发语言