因为延迟队列的需求非常多,而手动的用死信队列实现延迟队列也较为麻烦,所以RabbitMQ的官方也推出了一个插件,原生支持延迟队列效果。
这个插件就是DelayExchange插件。参考RabbitMQ的插件列表页面:https://www.rabbitmq.com/community-plugins.html
使用方式可以参考官网地址:https://blog.rabbitmq.com/posts/2015/04/scheduling-messages-with-rabbitmq
插件安装
-
运行mq容器
docker run
-e RABBITMQ_DEFAULT_USER=username
-e RABBITMQ_DEFAULT_PASS=password
-v mq-plugins:/plugins
–name mq
–hostname mq1
-p 15672:15672
-p 5672:5672
-d
rabbitmq:3.8-management
-
RabbitMQ有一个官方的插件社区,地址为:https://www.rabbitmq.com/community-plugins.html
其中包含各种各样的插件,包括我们要使用的DelayExchange插件:
可以去对应的GitHub页面下载3.8.9版本的插件,地址为https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/tag/3.8.9这个对应RabbitMQ的3.8.5以上版本。
-
挂载插件至mq的插件目录
docker volume inspect mq-plugins 查看数据卷的位置 使用cp 命令将插件复制到指定数据卷目录中
-
开启插件
最后就是安装了,需要进入MQ容器内部来执行安装。我的容器名为mq,所以执行下面命令: docker exec -it mq bash 执行时,请将其中的 -it 后面的mq替换为你自己的容器名. 进入容器内部后,执行下面命令开启插件: rabbitmq-plugins enable rabbitmq_delayed_message_exchange
DelayExchange原理
DelayExchange需要将一个交换机声明为delayed类型。当我们发送消息到delayExchange时,流程如下:
- 接收消息
- 判断消息是否具备x-delay属性
- 如果有x-delay属性,说明是延迟消息,持久化到硬盘,读取x-delay值,作为延迟时间
- 返回routing not found结果给消息发送者
- x-delay时间到期后,重新投递消息到指定队列
使用DelayExchange
插件的使用也非常简单:声明一个交换机,交换机的类型可以是任意类型,只需要设定delayed属性为true即可,然后声明队列与其绑定即可。
整体的队列交换机声明的代码如下
@Bean("exchange")
public DirectExchange setDirectChange(){
return ExchangeBuilder
.directExchange("feifei_direct") //声明交换机得名称及类型
.delayed() //声明为延迟交换机
.durable(true) //持久化交换机
.build();
}
@Bean("queue")
public Queue delayedQueue(){
return QueueBuilder.durable("delay_queue").build();
}
@Bean
public Binding binding(DirectExchange exchange,Queue queue){
return BindingBuilder.bind(queue).to(exchange).with("feifei");
}
生产者代码如下
Message message = MessageBuilder.withBody("菲菲肥肥肥".getBytes())
.setContentEncoding("utf-8")
.setHeader("x-delay", 20000)
.build();
CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
rabbitTemplate.convertAndSend("feifei_direct","feifei",message,correlationData);
总结
延迟队列插件的使用步骤包括哪些?
声明一个交换机,添加delayed属性为true
发送消息时,添加x-delay头,值为超时时间