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

RabbitMQ使用延迟消息

RabbitMQ使用延迟消息

1.什么情况下使用延迟消息

延迟消息适用于需要在一段时间后执行某些操作的场景,常见的有以下几类:

1.1. 订单超时取消(未支付自动取消)

场景: 用户下单后,如果 30 分钟内未付款,系统需要自动取消订单。

实现方式

  • 订单创建时,发送延迟消息30 分钟后检查订单状态。

  • 若订单仍未支付,则自动取消释放库存

2.支付后延迟发货 🚚

场景: 某些商品需要延迟发货,例如 7 天无理由退款期间不立即发货,等待用户是否申请退款。

实现方式

  • 用户付款后,发送延迟消息7 天后检查订单状态。

  • 如果用户未申请退款,则发货;否则取消发货。

3. 限时活动(抢购、秒杀等)

场景: 某些促销活动(如秒杀、限时抢购)在特定时间开始或结束

实现方式

  • 活动开始前,发送延迟消息,定时开放库存

  • 活动结束前,发送延迟消息,下架商品,停止抢购

2.延迟消息实现

这里使用第一种情况实现(下单未付款,特定时间内取消订单,恢复库存)

1.下载RabbitMQ的延迟消息插件,地址:

Releases · rabbitmq/rabbitmq-delayed-message-exchange

下载完将插件在docker中添加到RabbitMQ的plugins中,然后docker restart rabbitmq重启RabbitMQ

2.在交换机中添加新的交换机,类型中多了一个x-delayed-message,这表示延迟消息插件安装成功

3.使用注解声明延迟消息交换机

定义远驰消息交换机名字、延迟消息队列和routingkey

public interface MqConstants {
    String DELAY_EXCHANGE_NAME = "trade.delay.direct";
    String DELAY_ORDER_QUEUE_NAME = "trade.delay.order.queue";
    String DELAY_ORDER_KEY = "delay.order.query";
}
    /**
     * 监听延迟队列,如果订单下单未支付,则取消订单,恢复库存
     * @param orderId
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = MqConstants.DELAY_ORDER_QUEUE_NAME), //延迟队列名
            exchange = @Exchange(name = MqConstants.DELAY_EXCHANGE_NAME, delayed = "true"), //延迟交换机名
            key = MqConstants.DELAY_ORDER_KEY //routingkey
    ))
    public void listenOrderDelayMessage(Long orderId){
        // 1.查询订单
        Order order = orderService.getById(orderId);
        // 2.检测订单状态,判断是否已支付
        if(order == null || order.getStatus() != 1){
            // 订单不存在或者已经支付
            return;
        }
        // 3.未支付,需要查询支付流水状态
        PayOrderDTO payOrder = payClient.queryPayOrderByBizOrderNo(orderId);
        // 4.判断是否支付
        if(payOrder != null && payOrder.getStatus() == 3){
            // 4.1.已支付,标记订单状态为已支付
            orderService.markOrderPaySuccess(orderId);
        }else{
            // TODO 4.2.未支付,取消订单,回复库存
            System.out.println("订单未支付,取消订单,回复库存");
//            orderService.cancelOrder(orderId);
        }
    }
}

4.发送消息

用户下单完毕后,想延迟消息队列发送消息

//下单完毕后

        /**
         * TODO:发送延迟消息,查询10秒后订单的状态,如果没支付,则取消订单,恢复库存
         */
        rabbitTemplate.convertAndSend(
                MqConstants.DELAY_EXCHANGE_NAME,
                MqConstants.DELAY_ORDER_KEY,
                order.getId(),
                message -> {
                    message.getMessageProperties().setDelay(1000 * 10);//延迟时间10s
                    return message;
                }
        );

通过设置交换机名字和routingkey可以绑定到延迟消息队列

这里设置延迟时间为10s(方便测试),下单10s后会发送消息到延迟消息交换机,然后去判断用户是否支付,如果未支付,则取消订单恢复库存

3.实践

发送下单请求

控制台可以看到,下单到消费消息中间间隔十秒钟,表明我们设置的延迟消息成功

相关文章:

  • 升级到碳纤维齿轮是否值得?
  • CCF-CSP认证 202104-2邻域均值
  • 【js逆向】
  • 牛客周赛:84:C:JAVA
  • 亚信安全发布第七期《勒索家族和勒索事件监控报告》
  • 以太网基础Vlan划分实验
  • C++学习之QT综合项目二经典翻金币小游戏及打包
  • 【LeetCode合并区间C++实现】【c++】【合并区间】
  • javase集合框架List篇
  • ds回答 什么是数据召回
  • 【数据结构】二叉搜索树、平衡搜索树、红黑树
  • 【初探数据结构】带环链表:原理、判断与数学证明
  • 使用 Switch Plus 将 ADTS 文件转为 MP3 格式简单教程
  • 「mysql」Mac mysql一路畅通式安装
  • Linux基础开发工具—vim
  • 【JavaEE】SpringBoot快速上手,探秘 Spring Boot,搭建 Java 项目的智慧脚手架
  • 软件工程:软件开发之需求分析
  • volatile限定符
  • XXE靶机详细通关攻略(flag)
  • 订阅指南:用关键指标驱动业务增长
  • 韶关一企业将消防安装工程肢解发包,广东住建厅:罚款逾五万
  • 侵害孩子者,必严惩不贷!3名性侵害未成年人罪犯今日执行死刑
  • 外企聊营商|武田制药:知识产权保护助创新药研发
  • 【社论】打破“隐形高墙”,让老年人更好融入社会
  • 张汝伦:康德和种族主义
  • 一图看懂|印巴交火后,双方基地受损多少?