采用RabbitMQ的延迟队列和死信队列实现订单超时取消功能(自用)

1.什么是延迟队列?怎么实现的?

延迟队列指的是存储对应的延迟消息,消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

RabbitMQ 本身是没有延迟队列的,要实现延迟消息,一般有两种方式:

1.使用 RabbitMQ 的死信交换机(Exchange)和消息的存活时间 TTL(消息存活时间)。生产者将消息发送到一个特定的交换器,该交换器将这些消息路由到一个具有TTL属性的队列。当消息在队列中的时间超过设定的TTL值时,消息会被发送到死信队列。消费者可以从死信队列中获取这些消息并进行相应的处理。
2.可以使用 rabbitmq_delayed_message_exchange插件:这个插件允许交换器直接支持延迟消息的发布。使用此插件,生产者可以在发送消息时指定一个延迟时间,然后交换器会在该时间过后才将消息路由到相应的队列中。这样一来,消费者只能在延迟时间过后才能接收到消息。

2.在 RabbitMQ 中实现订单超时取消功能,可以通过结合使用延迟队列和死信队列来完成。以下是一个实现步骤:

  1. 创建订单队列和死信队列

    • 创建一个订单队列(orderQueue)用于接收订单请求。
    • 创建一个死信队列(deadLetterQueue)用于处理超时取消的订单。
  2. 设置延迟队列

    • 创建一个延迟队列(delayQueue)用于处理订单超时逻辑。此队列会设置一个消息过期时间(TTL),在时间到达后,消息会被发送到死信队列。
  3. 配置队列与交换机

    • 设置延迟队列的 TTL,配置消息的过期时间,并将延迟队列的 x-dead-letter-exchange 属性设置为死信交换机,x-dead-letter-routing-key 设置为死信队列的路由键。
    • 配置死信队列的交换机,确保超时的订单消息能够被正确路由到死信队列。
  4. 实现逻辑

    • 生产者在订单生成后生成一条带有TTL(例如 15分钟)的延迟取消订单消息。
    • 该消息被发送到延迟队列交换机,并通过绑定的路由键投递到延迟队列。
    • 在延迟队列中,消息的TTL到期后,消息会被发送到死信队列交换机。
    • 死信队列交换机将消息投递到死信队列。
    • 消费者监听死信队列的消息,一旦有消息,消费者会立即消费并执行超时取消的业务逻辑,例如更新订单状态和发送通知。

示例代码

以下是 RabbitMQ 的示例配置和代码片段:

1. 创建延迟队列和死信队列的配置

# 延迟队列的配置
rabbitmq:
  exchanges:
    delayExchange:
      type: direct
      durable: true
  queues:
    delayQueue:
      durable: true
      arguments:
        x-dead-letter-exchange: "deadLetterExchange"
        x-dead-letter-routing-key: "cancelOrder"
        x-message-ttl: 900000  # 消息过期时间,单位是毫秒 (15分钟)
    deadLetterQueue:
      durable: true
  bindings:
    delayQueue:
      exchange: delayExchange
      routing-key: order
    deadLetterQueue:
      exchange: deadLetterExchange
      routing-key: cancelOrder

2. 发送订单消息到延迟队列

// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
    // 声明交换机和队列
    channel.exchangeDeclare("delayExchange", "direct", true);
    channel.queueDeclare("delayQueue", true, false, false, null);
    channel.queueBind("delayQueue", "delayExchange", "order");
    channel.exchangeDeclare("deadLetterExchange", "direct", true);
    channel.queueDeclare("deadLetterQueue", true, false, false, null);
    channel.queueBind("deadLetterQueue", "deadLetterExchange", "cancelOrder");

    // 发送消息到延迟队列
    String message = "Order data";
    channel.basicPublish("delayExchange", "order", null, message.getBytes());
}

3. 处理死信队列中的超时订单

// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection(); Channel channel = connection.createChannel()) {
    channel.exchangeDeclare("deadLetterExchange", "direct", true);
    channel.queueDeclare("deadLetterQueue", true, false, false, null);
    channel.queueBind("deadLetterQueue", "deadLetterExchange", "cancelOrder");

    // 消费死信队列中的消息
    DeliverCallback deliverCallback = (consumerTag, delivery) -> {
        String message = new String(delivery.getBody(), "UTF-8");
        System.out.println("Received canceled order: " + message);
        // 执行超时取消逻辑,例如更新订单状态
    };
    channel.basicConsume("deadLetterQueue", true, deliverCallback, consumerTag -> { });
}

这样,当订单在延迟队列中超时后,它们会被转发到死信队列,并通过消费者处理超时取消逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值