首页 > 其他分享 >【Spring-RabbitMq】设置消费重试次数

【Spring-RabbitMq】设置消费重试次数

时间:2024-08-10 17:59:11浏览次数:12  
标签:String Spring RabbitMq 重试 次数 消息 message cause

引言

在我们实际项目中需要对消息消费的高可用做保证,首先需要做到的就是消息的重试机制,设想一下以下场景:

当库存服务处理上游服务发过来的订单消息时,此时服务宕机了,或者网络不可用了,那我这个消息是应该算消费成功还是消费失败呢?

显然,我们肯定要对处理不成功的消息进行重试,那么如果消费不成功的话,就要无限次数的重试吗?

答案是否,因为当代码逻辑有Bug或者上游的消息内容是错误的时候,无论再重试多少次也不会成功,此时应该将消息抛弃掉。

所以消费的最佳实践是:消息处理失败需要重试,且重试需要指定最大次数以及重试的时间间隔,当消息重试次数耗尽时,对消息做持久化处理。

那么该如何实现这个功能呢?由此引出今天的主题:针对Spring-RabbitMq,如何实现重试机制

功能实现

这一功能其实并不需要我们自己实现,Spring-RabbitMq已经为我们做好了,我们只需要进行一些配置。

重试机制的配置同样依赖RabbitListenerContainerFactory,对这个不熟悉的可以先阅读上一篇博客
【Spring-RabbitMq配置一个消费端接入多个vhost】

配置MethodInterceptor

spring-rabbitmq包下的org.springframework.amqp.rabbit.config.RetryInterceptorBuilder,该类是一个建造者,通过他可以配置重试机制,在我的项目中指定了最多重试5次,并且重试间隔是:重试初始间隔8秒.2倍递增,不超过60秒。

    /**
     * 重试机制
     * 重试初始间隔8秒.2倍递增,不超过60秒
     * 最多重试5次
     *
     * @return 重试模板
     */
    public MethodInterceptor createInterceptor() {
        return RetryInterceptorBuilder.stateless()
            .maxAttempts(8)
            .backOffOptions(8000, 2, 180 * 1000)
            // 指定消息重试达到最大次数后的回调
            .recoverer(messageRecoverer())
            .build();
        // RejectAndDontRequeueRecoverer: 重试最大次数后消息会一直处于 UnAcked 状态,当断开连接时,消息会转为 Ready,继续等待被消费
    }

配置重试次数耗尽后的策略MessageRecoverer

让我们看org.springframework.amqp.rabbit.retry.MessageRecoverer,这是一个函数式接口,在消息重试次数耗尽后,会我们执行这个方法。

package org.springframework.amqp.rabbit.retry;

import org.springframework.amqp.core.Message;

/**
 * @author Dave Syer
 * @author Gary Russell
 *
 */
@FunctionalInterface
public interface MessageRecoverer {

	/**
	 * Callback for message that was consumed but failed all retry attempts.
	 *
	 * @param message the message to recover
	 * @param cause the cause of the error
	 */
	void recover(Message message, Throwable cause);

}

在我的项目中,次数耗尽后,我们会把消息内容记录到日志中,并发出企业微信告警。

这里主要是结合具体业务,把消息转发到死信交换机或者持久化到数据库都是可以的。

    /**
     * 消息达到最大重试次数后的回调
     *
     * @return 已消费但所有重试失败的消息的回调。
     */
    private MessageRecoverer messageRecoverer() {
        return (message, cause) -> {
            String messageContent = new String(message.getBody(), StandardCharsets.UTF_8);
            log.error("消息达到最大重试次数,从队列删除,消息:{},message:{}", new String(message.getBody(), StandardCharsets.UTF_8), JSON.toJSONString(message));
            log.error("消息达到最大重试次数,异常",cause);

            try {
                String errorMsg = Optional.ofNullable(cause.getMessage()).map(msg -> msg.length() > 100 ? msg.substring(0, 100) : msg).orElse("");
                String notifyContent = weChatWarnMessageUtil.buildMqWarnMessage(StrUtil.format(MESSAGE_RECOVER_MSG, message.getMessageProperties().getConsumerQueue(),
                        messageContent, errorMsg),
                    "MQ消费异常");
                weChatWarnMessageUtil.send(notifyContent, WeChatNotifyContentType.MARKDOWM);
            } catch (Exception e) {
                log.info("企业微信告警失败", e);
            }
            throw new AmqpRejectAndDontRequeueException(null, true, cause);
        };
    }

最后,像上篇内容说的一样,配置好RabbitListenerContainerFactory,再与队列绑定即可。
在这里插入图片描述

标签:String,Spring,RabbitMq,重试,次数,消息,message,cause
From: https://blog.csdn.net/u014135956/article/details/141093652

相关文章

  • springboot+vue社区物品交换平台的管理与实现【程序+论文+开题】-计算机毕业设计
    系统程序文件列表开题报告内容研究背景随着社会的快速发展和物质生活的日益丰富,社区居民之间物品闲置与浪费现象日益凸显。一方面,许多家庭拥有大量不再使用但仍具使用价值的物品;另一方面,这些物品对于其他家庭而言可能正是所需。在此背景下,构建一个社区物品交换平台显得尤为......
  • 基于SpringBoot的大学生智能消费记账系统
    传统信息的管理大部分依赖于管理人员的手工登记与管理,然而,随着近些年信息技术的迅猛发展,让许多比较老套的信息管理模式进行了更新迭代,用户信息因为其管理内容繁杂,管理数量繁多导致手工进行处理不能满足广大用户的需求,因此就应运而生出相应的大学生智能消费记账系统。本大学生......
  • springbootAl农作物病虫害预警系统-计算机毕业设计源码21875
    基于Vue+SpringBoot的Al农作物病虫害预警系统的设计与实现摘要随着农业现代化的推进,农作物病虫害的防治已成为农业生产中的重要环节。传统的病虫害防治方法往往依赖于农民的经验和观察,难以准确、及时地预测和防控病虫害的发生。因此,开发一种基于现代信息技术的农作物病虫......
  • springboot垂钓服务系统-计算机毕业设计源码17434
    摘要本文旨在针对垂钓爱好者的需求,基于微信小程序平台,设计并实现一套垂钓服务系统。首先,通过对用户需求进行调研和分析,确定了系统的基本功能模块,包括垂钓点信息展示、用户预约和支付、钓具租赁信息等。接着,借助微信小程序提供的开发框架和组件库,实现了系统的界面设计和交互功......
  • 【计算机毕设论文】基于SpringBoot+Vue线上学习平台的设计与实现
    ......
  • 多模块 Spring 项目构建
    在一个多模块的Spring项目中,父模块通常被定义为一个pom.xml文件,包含所有子模块的公共配置、依赖和插件。子模块通过继承父模块的pom.xml文件,来共享和管理这些公共依赖和版本信息。实现步骤创建父模块(ParentModule):在父模块的pom.xml中,定义所有的依赖管理和版本控制......
  • 12.面试题——Spring Boot
    1.SpringBoot是什么?SpringBoot是Spring开源组织下的子项目,是Spring组件一站式解决方案,主要是简化了使用Spring的难度,简省了繁重的配置,提供了各种启动器,开发者能快速上手。2.为什么要用SpringBoot?快速开发快速整合第三方框架(Maven依赖关系,Maven继承)简化XML的配......
  • 免费【2024】springboot 高校竞赛管理系统的设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 免费【2024】springboot 高校教务管理系统设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 免费【2024】springboot 高校奖助学金系统的设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......