RabbitMQ 进阶 学习笔记2

这是 初步认识RabbitMQ 基础 学习笔记-CSDN博客 的后续

生产者的可靠性

生产者重连

生产者发送消息时会检测与MQ服务的连接,如果发生网络波动会出现连接失败的问题,可以通过生产者重连解决

生产者重连配置

生产者发送消息时会检测与MQ服务的连接,如果发生网络波动会出现连接失败的问题,可以通过在配置文件里配置:

当连接超时(connection-timeout),再等待ininitial-interval,后尝试连接,

若再次连接超时(connection-timeout),再等待initial-interval,后尝试连接,

这个过程会尝试max-attems次。

生产者重连注意事项

注意:1、生产者重连默认关闭,需设置enabled:true开启

2、multiplier参数:下此的ininitial-interval是上次的ininitial-interval的多少倍,例:设置为1,每次的ininitial-interval都相等

3、在生产者重连过程中,是阻塞的,例:这是一段代码:"发送给MQ"这个操作,由于连接到MQ失败,会进行生产者重连,重连成功后才会执行"后续代码",要合理设置生产者重连时间。

java 复制代码
······
发送给MQ;
后续操作;

生产者确认

1.当消息发送到了MQ的交换机,但是没有到达队列,此时会通过PublisherReturn返回异常原因+ACK,通知消息发送成功

2.(队列是非持久化队列)当消息发送到了MQ的交换机,且到达队列,PublisherConfirm会返回ACK,通知消息发送成功

3.(队列是持久化队列)当消息发送到了MQ的交换机,且到达队列,且完成持久化,PublisherConfirm会返回ACK,通知消息发送成功

4.其余情况都会返回NACK

生产者确认配置

1.配置文件

建议:选择corrlated模式,异步回调

2.配置ReturnCallback(指定一次)

ReturnCallback 仅在 "消息成功到达交换机,但无法路由到队列" 且满足触发前提时才会触发,并非每次发送消息都触发。

3.配置ConfirmCallback(为每个消息都指定)

每次消息都触发

生产者确认注意事项

  • 生产者确认需要额外的网络和系统资源开销,尽量不要使用
  • 如果一定要使用,无需开启 Publisher-Return 机制,因为一般路由失败是自己业务问题
  • 对于 nack 消息可以有限次数重试,依然失败则记录异常消息

MQ的可靠性

在默认情况下,RabbitMQ 会将接收到的信息保存在内存中以降低消息收发的延迟。这样会导致两个问题:

  • 一旦 MQ 宕机,内存中的消息会丢失(丢失)
  • 内存空间有限,当消费者故障或处理过慢时,会导致消息积压,引发 MQ 阻塞(慢)

消息持久化

消息持久化分为三个方面:交换机持久化、队列持久化、消息持久化

我们重点讲消息的持久化

  • 消息持久化:消息成功路由到持久化队列 后,RabbitMQ 会先将消息写入磁盘(持久化日志 rabbit@hostname.log),再存入内存(提升消费效率);注意:并非 "边入队列边同步写磁盘"(同步写会严重性能),而是异步刷盘(默认每 50ms 刷盘 / 或累计 1000 条刷盘),但会先记录到内存中的 "持久化缓冲区",确保宕机时未刷盘的消息也能通过缓冲区恢复;

  • 消息非持久化:消息仅存储在内存中,不会主动写入磁盘(除非触发 RabbitMQ 的 "内存阈值换页机制");

Lazy Queue

配置Lazy Queue

总结

消费者的可靠性

消费者确认机制

消费者消息确认机制配置

消费失败处理

当消费者出现异常后,消息会不断 requeue(重新入队)到队列,再重新发送给消费者,然后再次异常,再次 requeue,无限循环,导致 mq 的消息处理飙升,带来不必要的压力。

我们可以利用 Spring 的 retry 机制,在消费者出现异常时利用本地重试 ,而不是无限制的 requeue 到 mq 队列,如果本地重试次数耗尽还是失败,我们需要采用失败消息处理策略

配置本地重试

配置失败消息处理策略

总结

延迟消息

一、延迟消息的核心定义

延迟消息 (Delayed Message)是指:消息生产者发送到消息队列(MQ)后,不会被消费者立即消费,而是按照预设的延迟时间(或指定的触发时间),在达到时间条件后才被投递到消费端进行处理的消息。

简单说,延迟消息的核心是 "发送后不立即消费,等待指定时间再处理",本质是 MQ 提供的 "定时触发" 能力,解决 "业务操作需要延迟执行" 的场景(比如订单超时未支付自动关闭、定时提醒、任务延迟重试等)。

二、生活化例子理解

  1. 外卖订单超时取消:你下单后商家接单,平台发送一条 "延迟消息" 到 MQ,延迟时间设为 30 分钟;如果 30 分钟内你没付款,这条消息就会被触发,执行 "取消订单" 逻辑;如果付款了,就提前删除这条延迟消息。

  2. 定时喝水提醒:你在 APP 上设置 "1 小时后提醒喝水",APP 会向 MQ 发送一条延迟 1 小时的消息;1 小时后消息被消费,APP 给你推送提醒。

  3. 快递揽收超时预警:快递下单后,MQ 存入一条延迟 2 小时的消息;如果 2 小时内快递员未揽收,消息触发,系统给快递员发预警通知。

实现方式一:死信交换机(不推荐)

1.首先在 Spring Boot 项目中配置交换机、队列,并绑定死信交换机(DLX)

2.通过 RabbitTemplate 发送消息时,给消息设置 expiration 属性(单位:毫秒)

java 复制代码
   Message message = MessageBuilder.withBody(msgContent.getBytes())
                .setExpiration("30000") // TTL=30秒
                .build();

        // 发送消息到普通交换机+队列
        rabbitTemplate.send(
                "simple.direct",  // 交换机名
                "simple.rk",      // 路由键
                message           // 带TTL的消息
        );

实现方式二:延迟消息插件

RabbitMQ 的官方也推出了一个插件,原生支持延迟消息功能。该插件的原理是设计了一种支持延迟消息功能的交换机,当消息投递到交换机后可以暂存一定时间,到期后再投递到队列。

1.下载安装插件:略

GitHub上的下载地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases?page=1

2.配置延迟交换机:

3.设置延时消息

业务幂等性

业务幂等性是指:同一业务操作,无论被重复执行多少次,最终产生的业务结果和系统状态都是完全一致的,不会因重复执行导致数据异常。如重复下单不会生成多个订单、重复扣款不会扣多次钱。

解决方案一:唯一ID

解决方案二:业务判断

总结

相关推荐
leiming618 小时前
linux 进程学习之信号
linux·运维·学习
廋到被风吹走18 小时前
【消息队列】选型深度对比:Kafka vs RocketMQ vs RabbitMQ
kafka·rabbitmq·rocketmq
被遗忘的旋律.19 小时前
Linux驱动开发笔记(二十四)——(上)IIO + icm20608驱动
linux·驱动开发·笔记
zhangrelay19 小时前
thinkpad等笔记本电脑在ubuntu等linux系统下电池校准如何做?
笔记·学习
_Kayo_19 小时前
Node.JS 学习笔记8
笔记·学习·node.js
weixin_4624462319 小时前
使用 Docker / Docker Compose 部署 PdfDing —— 个人 PDF笔记
笔记·docker·pdf
知识分享小能手19 小时前
Oracle 19c入门学习教程,从入门到精通,Oracle 数据表对象 —— 语法知识点详解与案例实践(10)
数据库·学习·oracle
炽烈小老头19 小时前
【每天学习一点算法 2026/01/22】杨辉三角
学习·算法
枷锁—sha19 小时前
【CTF笔记篇】SQL 注入总结
数据库·笔记·sql·安全·网络安全
狐5719 小时前
2026-01-19-论文阅读-Agentic-Reasoning-for-Large-Language-Models
论文阅读·笔记