这是 初步认识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 提供的 "定时触发" 能力,解决 "业务操作需要延迟执行" 的场景(比如订单超时未支付自动关闭、定时提醒、任务延迟重试等)。
二、生活化例子理解
-
外卖订单超时取消:你下单后商家接单,平台发送一条 "延迟消息" 到 MQ,延迟时间设为 30 分钟;如果 30 分钟内你没付款,这条消息就会被触发,执行 "取消订单" 逻辑;如果付款了,就提前删除这条延迟消息。
-
定时喝水提醒:你在 APP 上设置 "1 小时后提醒喝水",APP 会向 MQ 发送一条延迟 1 小时的消息;1 小时后消息被消费,APP 给你推送提醒。
-
快递揽收超时预警:快递下单后,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

解决方案二:业务判断

总结
