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

文章目录

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

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

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

java 复制代码
// 生成订单之后,发送延迟消息
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 分钟)进行投递。这样,一旦消息被投递,它将会在延迟时间之后才会被消费。

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

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

java 复制代码
// 监听延迟队列,处理过期消息
@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() 方法就会立即返回该消息并触发订单取消逻辑。这种设计确保了消息可以被及时处理,而不会漏掉任何一个需要取消的订单。

三、取消订单的实现逻辑

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

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

相关推荐
懒大王爱吃狼43 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
瓜牛_gn1 小时前
mysql特性
数据库·mysql
奶糖趣多多2 小时前
Redis知识点
数据库·redis·缓存
阿伟*rui2 小时前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel
CoderIsArt3 小时前
Redis的三种模式:主从模式,哨兵与集群模式
数据库·redis·缓存
XiaoLeisj4 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck4 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei4 小时前
java的类加载机制的学习
java·学习
逐·風5 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
师太,答应老衲吧5 小时前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode