RabbitMQ高级:延迟消息

什么是延迟消息

其实就是如果支付服务确实不能通知交易服务去修改订单状态,那就让交易服务等30分钟,30分钟之后,如果交易服务还没有通知,就会主动去查支付服务,如果查到已支付,就更新订单状态,保证一致性。如果查到未支付,说明订单支付超时,直接取消订单。所以就需要一个延迟消息,要在下单那一刻发送,延迟一定时间后发给交易服务通知其去查支付服务。

死信交换机

利用了成为死信的第二个条件,过期消息。也就是publisher发送一个设置了TTL的消息到normal.queue,然后这个队列通过dead-letter-exchange属性指定了dlx.direct交换机,由于normal.queue没有消费者,所以这个消息在MQ里TTL过期之后,就会投递到dlx.direct,从而投递到consumer,实现了延迟消息。注意这里normal的交换机和队列的BindingKey要和dlx的交换机和队列的BindingKey一致,不然消息传不过去。

这是声明一个绑定了死信交换机的队列,也就是normal.queue。

复制代码
@Test
void testSendDelayMessage() {
    rabbitTemplate.convertAndSend("normal.direct", "hi", "hello", new MessagePostProcessor() {
        @Override
        public Message postProcessMessage(Message message) throws AmqpException {
            message.getMessageProperties().setExpiration("10000");
            return message;
        }
    });
}

这个是发送带TTL消息的代码,convertAndSend方法最后还可以带一个参数,叫做消息后置处理器,可以在Java对象转换为消息对象之后,对消息做处理。需要实现postProcessMessage方法,这个方法的形参就是转换后的消息,可以给它设置参数。

延迟消息插件

给RabbitMQ装了插件之后,就是设置个delayed属性,这个交换机就有了延迟消息的功能。

发消息也不一样了,变成setDelay了。

取消超时订单

这里是假设最坏情况,支付服务无法向MQ发送消息。

为啥要先查询本地订单状态呢,这是因为,如果本地订单状态是已支付,说明支付服务成功通知到交易服务了。交易服务自己发自己收。

相关推荐
城管不管11 小时前
重生——第九次面试2026.8.13某车一面
分布式·ai·面试·职场和发展·rabbitmq
apgk111 小时前
基于Canal实现mysql数据同步到消息队列(RabbitMQ/Kafka)详细操作教程
docker·kafka·rabbitmq
Rain的Java大神之路12 小时前
MQ重复消费问题怎么解决
java·经验分享·后端·面试·架构·rabbitmq·rocketmq
ly768912 小时前
分布式一致性算法详解:从 2PC、3PC 到 Paxos、Raft、ZAB
分布式·算法
珠***格13 小时前
通信链路全打通:西格电力四可装置的 4G/5G + 加密认证技术详解
大数据·数据库·分布式·5g·架构·能源
ACP广源盛1392462567314 小时前
WAIC2026 国产算力浪潮@ACP#YLB3118 在算力矩阵中的存储定位与落地场景
大数据·人工智能·分布式·单片机·嵌入式硬件
蜀道山老天师17 小时前
ZABBIX分布式监控Proxy应用实践
分布式·zabbix
liudashuang201717 小时前
Kafka Producer 隐藏深坑:Sender 线程自阻塞(自死锁)导致 BufferExhaustedException 完整复盘
java·分布式·kafka·linq
hard_hot19 小时前
RabbitMQ异步下单架构设计
java·rabbitmq·java-rabbitmq
rustfs19 小时前
GitLab 如何与 RustFS 集成?
分布式·rust·gitlab