首页 > 数据库 >利用 Redisson 实现延迟消息队列:一种高效订单取消方案

利用 Redisson 实现延迟消息队列:一种高效订单取消方案

时间:2024-08-29 22:23:59浏览次数:6  
标签:orderId Redisson 队列 订单 取消 消息 延迟

文章目录


在电商平台中,订单生成后如果长时间未被处理,我们通常需要自动取消这些订单。这种需求不仅能够提升用户体验,还能有效管理库存和资源分配。而如何实现这一需求,延迟消息队列无疑是一个高效的解决方案。今天,我们就来聊聊如何使用 Redisson 实现一个简洁且强大的延迟消息处理机制。

一、发送延迟消息:定时触发订单取消

首先,我们需要在生成订单之后,立即发送一个延迟消息。在这个方法中,我们使用了 Redisson 的 RBlockingQueueRDelayedQueue 来实现消息的延迟发送。

// 生成订单之后,发送延迟消息
private void sendDelayMessage(Long orderId) {
    try {
        // 1. 创建阻塞队列,用于存储待取消订单的消息
        RBlockingQueue<Object> blockingQueue = redissonClient.getBlockingQueue("queue_cancel");

        // 2. 将创建的阻塞队列放入延迟队列中
        RDelayedQueue<Object> delayedQueue = redissonClient.getDelayedQueue(blockingQueue);

        // 3. 发送消息到延迟队列中,并设置15分钟的延迟时间
        delayedQueue.offer(orderId.toString(), 15, TimeUnit.MINUTES);
    } catch (Exception e) {
        e.printStackTrace();
        throw new GuiguException(ResultCodeEnum.DATA_ERROR);
    }
}

在这个方法中,blockingQueue 是一个标准的阻塞队列,而 delayedQueue 则是一个延迟队列,负责将消息按照设定的延迟时间(这里是 15 分钟)进行投递。这样,一旦消息被投递,它将会在延迟时间之后才会被消费。

二、监听延迟队列:自动处理过期订单

消息发送后,我们还需要有一个机制来监听这些延迟消息,并在消息过期时自动处理。这就是监听延迟队列的功能。

// 监听延迟队列,处理过期消息
@Component
public class RedisDelayHandle {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private OrderInfoService orderInfoService;

    @PostConstruct
    public void listener() {
        new Thread(() -> {
            while (true) {
                // 获取延迟队列中的阻塞队列
                RBlockingQueue<String> blockingQueue = redissonClient.getBlockingQueue("queue_cancel");

                // 从队列中获取消息
                try {
                    String orderId = blockingQueue.take();

                    // 取消订单操作
                    if (StringUtils.hasText(orderId)) {
                        // 调用订单取消方法
                        orderInfoService.orderCancel(Long.parseLong(orderId));
                    }

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }
}

在这里,我们使用了一个新线程来持续监听阻塞队列 blockingQueue。一旦有消息被投递到该队列中,blockingQueue.take() 方法就会立即返回该消息并触发订单取消逻辑。这种设计确保了消息可以被及时处理,而不会漏掉任何一个需要取消的订单。

三、取消订单的实现逻辑

监听到延迟消息后,我们需要实际执行订单取消操作。下面是一个简单的取消订单的实现逻辑:

@Override
public void orderCancel(long orderId) {
    // 根据 orderId 查询订单信息
    OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

    // 判断订单状态是否为待接单
    if (orderInfo.getStatus() == OrderStatus.WAITING_ACCEPT.getStatus()) {
        // 修改订单状态为取消状态
        orderInfo.setStatus(OrderStatus.CANCEL_ORDER.getStatus());
        int rows = orderInfoMapper.updateById(orderInfo);

        if (rows == 1) {
            // 删除接单标识
            redisTemplate.delete(RedisConstant.ORDER_ACCEPT_MARK);
        }
    }
}

这个方法中,我们首先通过 orderId 查询订单信息。如果订单状态为待接单,则将其状态更新为取消状态,并删除接单标识。这样,系统就成功地通过延迟消息队列实现了订单的自动取消。

四、总结

利用 Redisson 实现延迟消息队列是一种高效的订单管理策略。通过这种方式,我们不仅能够精确地控制订单的处理时效,还可以大幅提升系统的稳定性和响应速度。同时,这种实现方式相对简单,易于维护和扩展。

标签:orderId,Redisson,队列,订单,取消,消息,延迟
From: https://blog.csdn.net/Takumilove/article/details/141607648

相关文章

  • 数据结构与算法 第3天(栈和队列)
    栈和队列也是线性表,限制插入和删除的位置只能在端点栈(stack)后进先出LIFO表尾进入,表尾删除一、案例案例一:进制转换例子159转换成八进制159/8=19...719/8=2...32/8=0...2结果为237案例二:括号匹配的检验左括号先入栈,右括号有匹配的话与左括号一起出栈案例三:表......
  • Redisson分布式延迟队列
    Redisson是一个基于redis实现的Java驻内存数据网格,它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。Redisson除了提供我们常用的分布式锁外,还提供了一个分布式延迟队列RDelayedQueue,他是一种基于zset结构实现的延迟队列,其实现类是RedissonDelayedQu......
  • JDK延迟队列 DelayQueue
    DelayQueue是JDK提供的一个无界队列,我们可以看到,DelayQueue队列中的元素需要实现Delayed,它只提供了一个方法,就是获取过期时间。用户的订单生成以后,设置过期时间比如30分钟,放入定义好的DelayQueue,然后创建一个线程,在线程中通过while(true)不断的从DelayQueue中获取过期的数据。......
  • 学习笔记2——队列(C++版)
    注意了,这里说的队列并不是STL容器库里面的queue。像链表、队列、栈、二叉树其实是一种数据结构,而vector、queue、set等是容器,是不同的概念。队列的实现可以有很多方式,可以用结构体内储存数组来实现,也可以用结构体内储存结构体来实现,我们这里选择后者。如何实现一个队列1.......
  • 数据结构(C)---双端队列(Deque)
    在使用本博客提供的学习笔记及相关内容时,请注意以下免责声明:信息准确性:本博客的内容是基于作者的个人理解和经验,尽力确保信息的准确性和时效性,但不保证所有信息都完全正确或最新。非专业建议:博客中的内容仅供参考,不能替代专业人士的意见和建议。在做出任何重要决定之前,请咨询相......
  • MySQL 延迟从库介绍
    前言:我们都知道,MySQL主从延迟是一件很难避免的情况,从库难免会偶尔追不上主库,特别是主库有大事务或者执行DDL的时候。MySQL除了这种正常从库外,还可以设置延迟从库,顾名思义就是故意让从库落后于主库多长时间,本篇文章我们一起来了解下MySQL中的延迟从库。延迟从库介绍延迟复......
  • 系统编程-消息队列
    消息队列目录消息队列引入一、消息队列的特点二、使用指令查看消息队列三、使用消息队列进行通信的步骤1、获取键值2、创建或获取消息队列id3、使用消息队列进行数据的传输4、msgrcv--从消息队列中读取数据5、消息队列的多种操作函数引入--进程间通信(IPC)......
  • 消息队列MQ的使用
    承接我的另一篇博客 消息队列MQ-CSDN博客启动服务1.启动mqnamesrv2.启动mqbrokermqbroker-n127.0.0.1:9876应用1.普通消息同步发送publicclassEasyA{publicstaticvoidmain(String[]args)throwsMQClientException,MQBrokerException,RemotingExce......
  • 单调队列--滑动窗口最大值(leetcode23)
    目录一、单调队列介绍二、题目应用1.题目描述2.解题碎碎念3.代码示例三、扩展1.与优先队列区别2.单调队列其他题目一、单调队列介绍单调队列是一种特殊的队列数据结构,它能够在常数时间内找到队列中的最值。单调队列可以用来解决一些与最值相关的问题,例如滑动窗口最......
  • MQ根据正常队列、死信队列来实现延迟队列的场景
     1、在RabbitMQ的管理后台新建交换机(exchange);名称(Name):**ParkingExchange**类型(Type):**fanout**持久化(Durability):**Durable**2、在RabbitMQ的管理后台新建队列(queue);名称(Name):**ParkingQueue**类型(Type):**Classic**(新版本RabbitM......