目录
用途
延迟队列在以下场景中应用广泛:
1. 订单超时处理:当用户下单后,可以将订单放入一个延迟队列中,在一定的时间后检查订单是否完成支付。如果订单未及时支付,可以触发相应的超时处理逻辑,如取消订单、释放库存等操作。
2. 消息重试机制:当某个消息无法被立即处理时,可以将该消息放入延迟队列,并设置延迟时间。在延迟时间到达后,将消息重新发送到原始队列,供消费者重新处理。
3. 定时任务调度:延迟队列可以用于实现定时任务的调度。将需要执行的任务放入延迟队列,并设置合适的延迟时间,当延迟时间到达时,任务会被获取并执行。
4. 优惠券过期提醒:在发放优惠券时,可以同时将过期时间放入延迟队列。当优惠券过期时间到达时,系统可以发送提醒消息给用户,以提醒其使用优惠券。
5. 延迟通知和提醒:在需要延迟通知或提醒的场景中,可以将通知信息放入延迟队列,并设置适当的延迟时间。当延迟时间到达后,系统会从队列中获取通知信息并发送给相应的用户。
总之,延迟队列适用于需要推迟某些操作或按照一定时间顺序处理任务的场景。这样可以提高系统的灵活性和可靠性,并且能够更好地处理异步任务和实时性要求不高的业务需求。
希望以上示例能够帮助你理解延迟队列的应用场景!如果还有其他问题,请随时提问。
延迟插件下载安装
下载插件文件:
- 访问 RabbitMQ Delayed Message Plugin 的 GitHub 仓库:GitHub - rabbitmq/rabbitmq-delayed-message-exchange: Delayed Messaging for RabbitMQ
- 在页面上找到 "Releases" 标签并进入。
- 下载与你当前 RabbitMQ 版本相对应的插件压缩包(以
.ez
或.tar.gz
结尾)。确保选择正确的版本。安装插件:
- 停止 RabbitMQ 服务(如果正在运行)。
- 将下载的插件压缩包解压缩。
- 将解压后得到的
.ez
文件复制到 RabbitMQ Server 的plugins
目录中,该目录通常位于 RabbitMQ 的安装目录下。- 启动 RabbitMQ 服务。
启用插件:
- 打开命令行终端并导航到 RabbitMQ Server 的
sbin
目录中,该目录通常位于 RabbitMQ 的安装目录下。- 运行以下命令启用插件:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
验证插件是否已启用:
- 在浏览器中访问 RabbitMQ 管理界面,默认地址为
http://localhost:15672
。- 使用管理员账号和密码登录。
- 导航到 "Exchanges" 部分,新增交换机,类型选择下拉框存在x-delayed-message,则说明安装成功
@Bean配置(交换机和队列绑定)
@Bean
public Queue queue() {
return new Queue("direct_delayed", true, false, false);
}
@Bean
public CustomExchange exchange() {
Map<String, Object> arguments = new HashMap<>(1);
arguments.put("x-delayed-type", "direct");
return new CustomExchange("delay_exchange", "x-delayed-message", true, false, arguments);
}
@Bean
public Binding directBindingOne(Queue queue, Exchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("one").noargs();
}
消费者
Logger logger = LoggerFactory.getLogger(ConsumerDirect.class);
@RabbitListener(bindings = @QueueBinding(
value = @Queue("direct_delayed"),
exchange = @Exchange(name = "delay_exchange", type = ExchangeTypes.DIRECT),
key = {"one"}
))
public void readDirectQueueOne(String msg) {
logger.info("当前时间为:{},仅接收key为one的队列的消息,接收到的信息为:{}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), msg);
}
模拟生产者发送消息
@GetMapping("send")
public void test(String key, int time) {
rabbitTemplate.convertAndSend(
"delay_exchange",
key,
"发送消息到路由键为" + key + "的队列中", message -> {
logger.info("当前时间为:{}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// message.getMessageProperties().setHeader("x-delay", 1000 * time);
message.getMessageProperties().setDelay(1000 * time);
return message;
}
);
}
注意:如果启动报错,要先在平台上创建交换机和队列,以及交换机和队列之间的关系