一、延迟队列的定义
概述:延迟队列是一种用来存放需要在指定时间之后或之前被处理的元素的队列。队列中的每个元素都指定了一个延迟时间,该时间表示元素应该在何时被取出并处理。在延迟时间到达之前,元素会保持在队列中,不会被消费者立即消费。
二、延迟队列的实现
1、基于死信队列实现延迟队列:
(1)、首先主要创建两个队列一个普通队列一个死信队列,将普通队列绑定到创建的死信队列并设置普通队列TTL.
//普通交换机//队列绑定等 ....................................... //普通队列 @Bean("orderExpiredQueue") public Queue delayQueueOrder(){ Map<String, Object> args = new HashMap<>(); //设置消息过期时间 args.put("x-message-ttl", 3600000); //设置死信交换机 args.put("x-dead-letter-exchange", DEAD_EXCHANGE_NAME); //设置死信 routing_key args.put("x-dead-letter-routing-key", DEAD_ROUTING_KEY); return new Queue(QUEUE_EXPIRED_ORDER, true, false, false, args); }
//死信交换机 @Bean("deadExchange") public DirectExchange deadOrderExchange(){ return new DirectExchange(DEAD_EXCHANGE_NAME, true, false); }
//死信队列 @Bean("deadQueue") public Queue deadOrderQueue(){ return QueueBuilder.durable(DEAD_ORDER_QUEUE) .build(); }
//绑定死信队列 @Bean public Binding deadOrderBingQueue(@Qualifier("deadExchange") DirectExchange directExchange,@Qualifier("deadQueue") Queue queue){ return BindingBuilder.bind(queue).to(directExchange).with(DEAD_ORDER_ROUTING_KEY); }
(2)之后在创建好具有TTL(Time-To-Live,生存时间)特性的队列后,实现延迟队列通常涉及将消息发送到该队列,并设置消息的TTL值作为延迟时间。当消息在队列中的存活时间超过TTL值时,消息会自动变成死信(如果配置了死信交换机和队列),随后这些死信可以被发送到另一个队列(即死信队列),从而实现了延迟队列的效果。
(3)只需要监听这个死信队列 消费这个死信队列的消息就可以了
@RabbitListener(queues = RabbitConfig.DEAD_ORDER_QUEUE) public void Message(JSONObject msg, Channel channel, Message message) throws IOException { //处理相关逻辑 }
2、基于RabbitMQ的插件实现延迟队列:
(1)参考下载步骤
参考步骤:也可以使用docker相关命令下载
- 下载插件
你可以从 RabbitMQ 的 GitHub Releases 页面下载 x-delayed-message 插件的 .ez 文件。确保选择与你的 RabbitMQ 服务器版本兼容的插件版本。以下是下载的通用步骤:
访问插件下载页面: 前往 RabbitMQ GitHub Releases - Delayed Message Exchange 页面。
选择合适的版本: 找到与你的 RabbitMQ 服务器版本兼容的插件版本,点击下载链接。
下载插件文件: 例如,使用 wget 或直接点击链接下载插件文件到本地。
wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/v3.8.17/rabbitmq_delayed_message_exchange-3.8.17.ez
确保 .ez 文件下载完整。- 安装插件
下载 .ez 文件后,需要将其放置到 RabbitMQ 服务器的插件目录中。
Linux
将 .ez 文件移动到 RabbitMQ 的插件目录:
sudo mv rabbitmq_delayed_message_exchange-3.8.17.ez /usr/lib/rabbitmq/lib/rabbitmq_server-<version>/plugins/
启用插件:
sudo rabbitmq-plugins enable rabbitmq_delayed_message_exchange
重启 RabbitMQ 服务:
sudo systemctl restart rabbitmq-server
(2)创建队列
@Bean Queue queue() { return new Queue(QUEUE_NAME, true, false, false); } @Bean CustomExchange customExchange() { Map<String, Object> args = new HashMap<>(); args.put("x-delayed-type", "direct"); return new CustomExchange(EXCHANGE_NAME, EXCHANGE_TYPE, true, false,args); } @Bean Binding binding() { return BindingBuilder.bind(queue()) .to(customExchange()).with(QUEUE_NAME).noargs(); }
(3)之后就可以监听队列测试了
3、两种方法的优缺点分析:
3.1、使用专门的延迟队列插件
优点:
- 精确控制:插件通常提供了精确控制延迟时间的能力,可以非常准确地设置消息的延迟时间。
- 性能优化:插件的实现往往针对延迟队列的特性进行了优化,可以提供更好的性能和效率。
- 简单易用:一旦插件安装并配置好,使用延迟队列就像使用普通队列一样简单,降低了使用的复杂度。
缺点:
- 依赖插件:需要下载、安装并启用RabbitMQ的插件,增加了系统的复杂性和维护成本。
- 版本兼容性:插件可能与RabbitMQ的某些版本不兼容,需要仔细选择插件版本。
- 功能限制:插件的功能可能受限于其开发团队的更新和维护,可能存在功能不足或更新滞后的问题。
3.2、使用死信队列配合TTL特性
优点:
- 无需额外插件:仅使用RabbitMQ的基本功能即可实现,无需安装额外的插件,降低了系统的复杂性。
- 灵活性高:可以灵活设置不同的TTL时间和死信队列,以满足不同的延迟需求。
- 易于理解:基于RabbitMQ的现有机制实现,易于理解和维护。
缺点:
- 精确性较低:由于TTL的粒度限制(如秒级或分钟级),可能无法实现非常精确的延迟时间。
- 性能考虑:当延迟消息较多时,死信队列可能会成为性能瓶颈,需要合理配置和管理。
- 复杂性增加:虽然不需要额外插件,但配置和管理死信队列和TTL可能会增加一定的复杂性。
版权归原作者 峰屹奕 所有, 如有侵权,请联系我们删除。