示例业务场景:
场景1:客户下单后,15分钟内未支付取消订单!
场景2:客户下单支付成功后,5分钟内商家未处理订单,需要推送一条消息提醒商家。如依旧未处理,则需要每隔2分钟消息提醒一下商家!
这两种场景都是可以使用延迟消息来实现,rabbitMq 提供了2种实现延迟消息的方式,死信队列 和 延迟插件;
使用docker 安装部署 rabbitMq
1,下载rabbitMq镜像;
docker pull rabbitmq
2,启动rabbitMq 容器;
docker run -d --name rabbit001 -p 15672:15672 -p 5672:5672 rabbitmq -v rabbitMq:/etc/rabbitmq rabbitmq
3,运行完成后,rabbitMq 服务通过ip+15762 访问后管平台;
如果访问不了,则需要在容器内安装可视化插件;(在容器内的/plugins 目录内执行)
rabbitmq-plugins enable rabbitmq_management
4,安装延迟插件;
1,在官网内下载对应版本的延迟插件上传到服务器内;(例如在官网下载的延迟插件放在了/home/rabbitmq目录内)
docker cp /home/rabbitmq/rabbitmq_delayed_message_exchange-3.12.0.ez 4296be33b41e:plugins/
2,然后再进入容器内安装延迟插件;
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
5,重启rabbitMq容器再通过ip+15672 访问即可!初始登录账户密码:guest/guest
6,修改默认密码;
1,进入容器内;2,查看用户列表:rabbitmqctllist_users3,修改guest密码(尽量设置复杂点):rabbitmqctlchange_passwordguest'@#20231126%&*'
7,通过死信队列实现延迟消息配置;
1,建立交换机:order-reserve-echage2,建立队列 dead-queues,参数如下设置x-dead-letter-exchange:order-reserve-echagex-dead-letter-routing-key:key2x-message-ttl:900000durable:true3,建立队列 receivedq,无其他参数;4,再进到刚刚建立的交换机 order-reserve-echage 内去绑定路由键;dead-queues key1receivedq key2
8,使用延时插件创建延迟队列;
1,建立延迟交换机:delayed-exchange注意:Type 是 x-delayed-messages 类型;添加一个参数:x-delayed-typedirect2,然后建立一个队列: delayed-queue ,无其他参数;3,然后再进到交换机 delayed-exchange 内去绑定路由键; delayed-queue delayed-routing-key
以上 rabbitMq 安装配置好之后做以下介绍:
问:什么是死信队列?
就是一个普通的队列,只不过我们自行做两点约束:1,设置了队列、或发往队列内的消息要有过期时间;2,要确保没有消费者主动订阅消费该队列内的消息;
问:死信队列如何实现延迟消息的?
需要创建2个队列,一个死信队列,一个普通的队列。且需要创建一个交换机去绑定这两个队列。在创建死信队列时,需要指定一个 x-dead-letter-routing-key (也就是消息过期后需要重新发往的队列)。我们发送消息到死信队列内,消息过期后会由交换机转发到 死信队列绑定的 x-dead-letter-routing-key 上。这个时候我们只需要监听普通队列即可。例如:我们想要发一条消息 15 分钟后收到这条消息。那么我们就可以发送一条过期时间为15分钟的消息到 死信队列,在没有任何消费者消费的情况下,15分钟后这条消息会过期,过期后会由交换机转发给绑定的普通队列内,这时我们在 普通队列接受到的消息就是15分钟前发送的消息!
问:死信队列 和 延迟插件 实现的延迟消息有什么不同?
死信队列:先发的消息会先收到,后发的消息会后收到,不会受设置的消息过期时间控制;例如:我先往死信队列内发一条15分钟后后期的消息,再发一条 3分钟后过期的消息。我们肯定是想先收到3分钟过期的消息,但是受队列特性的影响(先入先出),我们只有在消费了先发的15分钟过期的消息后才能收到那条3分钟的消息!!!延迟插件:不会出现以上情况,以设置的过期时间先后顺序接收到消息!先发了 一条 15分钟延迟消息,再发一条 3分钟过期消息,会先收到 3分钟过期的消息
以上两种业务场景实现思路:
场景1:客户下单后,15分钟内未支付取消订单!
1,客户下单后发送一条15分钟的延迟消息,消息内带有 订单的id;2,监听到延时消息后,拿到消息id去查询一下订单信息,如还未支付则取消订单。
场景2:客户下单支付成功后,5分钟内商家未处理订单,需要推送一条消息提醒商家。如依旧未处理,则需要每隔2分钟消息提醒一下商家!
1,客户下单支付成功后发送一条5分钟的延时消息,消息内带有订单id;2,5分钟后监听到消息,则去判断下当前订单是否有没有被处理,如果还没被处理则提醒商家。并且再发一条2分钟的延时消息!3,2分钟后再次监听到该消息后重复此步骤,如果商家未处理则提醒,并且再发延迟消息!