当前位置: 首页 > news >正文

RabbitMQ 如何使用延迟队列

RabbitMQ 如何使用延迟队列

目录

  1. 前置条件
  2. 场景描述
  3. RabbitMQ 延迟队列机制
  4. 实现步骤
    • 1. 安装 RabbitMQ 延迟队列插件
    • 2. 创建延迟队列和交换机
    • 3. 发布延迟消息
    • 4. 消费延迟消息
  5. 示例代码
    • 1. 延迟队列配置
    • 2. 发布消息的 Producer 代码
    • 3. 消费消息的 Consumer 代码
  6. 注意事项

前置条件

  • 操作系统:CentOS 7
  • RabbitMQ:版本 3.8.0+
  • Erlang:版本 21.0+
  • RabbitMQ 延迟队列插件:rabbitmq_delayed_message_exchange

场景描述

假设我们正在设计一个线上售卖电影票的系统,用户购票后有 15 分钟时间进行付款,如果用户在 15 分钟内未付款,订单将自动取消并释放电影票库存。这里,我们可以利用 RabbitMQ 的延迟队列机制,在用户购票时发送一条延迟消息到 RabbitMQ,并设定延迟时间为 15 分钟。如果用户未在 15 分钟内完成付款,延迟消息将被消费者接收并处理订单取消的逻辑。

RabbitMQ 延迟队列机制

RabbitMQ 本身不直接支持延迟队列功能,需要借助 rabbitmq_delayed_message_exchange 插件来实现。该插件为 RabbitMQ 提供了一种新的消息交换机类型——x-delayed-message,可以基于消息属性设置延迟时间,在设定的延迟时间后,将消息发送到目标队列。

实现步骤

1. 安装 RabbitMQ 延迟队列插件

# 下载插件
wget https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/download/v3.8.0/rabbitmq_delayed_message_exchange-3.8.0.ez# 将插件移动到 RabbitMQ 插件目录
mv rabbitmq_delayed_message_exchange-3.8.0.ez /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.0/plugins/# 启用插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange

2. 创建延迟队列和交换机

我们将使用 x-delayed-message 类型的交换机,并设定延迟队列,用于处理延迟消息。

# 创建交换机
rabbitmqadmin declare exchange name=delayed_exchange type=x-delayed-message \arguments='{"x-delayed-type":"direct"}'# 创建队列
rabbitmqadmin declare queue name=delayed_queue# 绑定交换机与队列
rabbitmqadmin declare binding source=delayed_exchange destination=delayed_queue routing_key=order.payment

3. 发布延迟消息

在发布消息时,可以设置消息属性 x-delay 来指定延迟时间。

# 使用 rabbitmqadmin 发布延迟消息
rabbitmqadmin publish exchange=delayed_exchange routing_key=order.payment \payload="{'order_id': '12345', 'status': 'PENDING_PAYMENT'}" \properties='{"headers":{"x-delay":900000}}'

4. 消费延迟消息

消费者将从延迟队列中消费消息并执行订单取消逻辑。

示例代码

1. 延迟队列配置

在 Spring Boot 项目中,可以通过以下配置来创建延迟交换机和队列。

@Configuration
public class RabbitConfig {public static final String DELAYED_EXCHANGE_NAME = "delayed_exchange";public static final String DELAYED_QUEUE_NAME = "delayed_queue";public static final String ROUTING_KEY = "order.payment";// 创建延迟交换机@Beanpublic CustomExchange delayedExchange() {Map<String, Object> args = new HashMap<>();args.put("x-delayed-type", "direct");return new CustomExchange(DELAYED_EXCHANGE_NAME, "x-delayed-message", true, false, args);}// 创建延迟队列@Beanpublic Queue delayedQueue() {return new Queue(DELAYED_QUEUE_NAME);}// 绑定延迟队列与交换机@Beanpublic Binding delayedBinding(Queue delayedQueue, CustomExchange delayedExchange) {return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(ROUTING_KEY).noargs();}
}

2. 发布消息的 Producer 代码

@Component
public class OrderProducer {@Autowiredprivate RabbitTemplate rabbitTemplate;public void sendOrderMessage(String orderId) {Map<String, Object> message = new HashMap<>();message.put("order_id", orderId);message.put("status", "PENDING_PAYMENT");MessageProperties messageProperties = new MessageProperties();messageProperties.setHeader("x-delay", 15 * 60 * 1000); // 延迟 15 分钟Message msg = new Message(new ObjectMapper().writeValueAsBytes(message), messageProperties);rabbitTemplate.convertAndSend(RabbitConfig.DELAYED_EXCHANGE_NAME, RabbitConfig.ROUTING_KEY, msg);}
}

3. 消费消息的 Consumer 代码

@Component
public class OrderConsumer {@RabbitListener(queues = RabbitConfig.DELAYED_QUEUE_NAME)public void processOrderCancellation(Message message) {try {Map<String, Object> orderMessage = new ObjectMapper().readValue(message.getBody(), Map.class);String orderId = (String) orderMessage.get("order_id");// 取消订单逻辑System.out.println("Order " + orderId + " has been canceled due to non-payment.");} catch (Exception e) {e.printStackTrace();}}
}

注意事项

  1. 插件兼容性:请确保 rabbitmq_delayed_message_exchange 插件与您的 RabbitMQ 版本兼容,否则可能导致插件无法加载。
  2. Erlang 版本:RabbitMQ 依赖于 Erlang,因此确保您的 Erlang 版本满足 RabbitMQ 版本的最低要求。
  3. 延迟时间限制:合理设置延迟时间,避免消息被延迟过长时间导致系统不可预测的性能问题。
http://www.lryc.cn/news/347858.html

相关文章:

  • 【C++】栈和队列
  • 常用的预编码算法学习
  • 人才培养计划大纲
  • 多语言环境下的正则表达式实战:校验整数、小数
  • 过拟合和欠拟合的学习
  • 中间件的使用
  • 阿里云OSS权限开通步骤及最佳实践
  • 【Python贪吃蛇】:编码技巧与游戏设计的完美结合
  • 2024.5.19 机器学习周报
  • 母亲节祝福html源码示例
  • 微信小程序开发中的权限管理与用户身份验证:守护数据安全与用户体验
  • Python3 笔记:二进制的转换
  • 代码审计-PHP模型开发篇动态调试反序列化变量覆盖TP框架原生POP链
  • 前端动态旋转地球背景
  • MySQL中的子查询
  • Unity打开安卓设备不同的设置面板
  • 低空经济+无人机:低空物资运输技术详解
  • 全场景智能终端RK3288主板在智能垃圾回收项目的应用,支持鸿蒙,支持全国产化
  • QT设计模式:建造者模式
  • 个人微信api
  • 使用Ownips工具获取海外电商网站wish商品价格
  • 【FFmpeg】调用ffmpeg进行H264软解
  • 网络安全防护:抵御DDoS和CC攻击
  • 初次查询大数据信用报告,需要注意哪些问题?
  • 最短路径[floyd算法]-----视频讲解+代码实现
  • 图像/视频恢复和增强CodeFormer
  • WPF中ObservableCollection
  • 如何用鼠标点击在picturebox的图像上做标记
  • k8s介绍
  • K-means聚类模型:深入解析与应用指南