阅读 466

基于RabbitMQ的延迟队列

用途

当用户下单后需要30分钟内付款,如果超过这个时间后自动取消订单。像这种情况我们就可以使用延时队列来处理,即发送一条延迟时间为30分钟的消息。

当然上述的场景用调度也能实现,这种方式相对于通过调度来进行处理有两个好处:

1. 性能更好,调度的话需要没每次对所有的订单数据进行遍历,判断哪些是已经过期的,然后进行取消操作。

2. 时间更精确,因为两次调度执行之间会有时间间隔,所以调度的方式可能造成一定的延后。

延迟队列的实现方案

通过死信(不推荐用)

RabbitMQ的Queue可以配置x-dead-letter-exchange和x-dead-letter-routing-key两个参数,当队列内出现了dead letter,则按照这两个参数重新路由。

x-dead-letter-exchange:出现dead letter后将dead letter重新发送到指定的exchange

x-dead-letter-routing-key:指定routing-key发送

出现dead letter的情况有

消息或者队列的TTL过期

队列达到最大长度

消息被消费端拒绝。

大致的思路就是:创建死信队列(死信队列是没有消费者的队列,到时间后就成为死信),然后创建死信转发队列,需要在私信消息那里进行配置。

不足:消息可能并不会按时死亡,因为RabbitMQ只会判断第一个消息是否过期,如果过期就丢到死信队列中,如果第一个消息延迟时间很长,而第二个消息延迟时间很短,第二个消息并不会优先得到执行。

通过插件

首先去官网下载延迟插件:www.rabbitmq.com/community-p…

根据自己rabbitMQ的版本选择下载不同的版本,我用的是3.8.9的版本。

由于我是使用docker启动的mq,所以还要执行把文件拷贝到容器的操作。

首先查看运行的容器,得到容器的ID

然后把文件复制到对应的容器当中:使用docker cp命令

执行下面的命令进入到容器查看下:docker exec -it  容器ID   /bin/bash

下面可以看到容器中已经有我们的文件了

如果在plugins目录下执行命令:rabbitmq-plugins enable rabbitmq_delayed_message_exchange

打开RabbitMQ的管理页面,我们看到x-delayed-message已经出来了,这样就可以定义延迟队列了。

定义队列和交换机

发送消息代码:

接收消息代码:

注意:延迟的时间有最大的限制(*2^32)-1毫秒,这个时间大约49天),超过了时间范围的消息会被立即消费。

文章分类
后端
文章标签