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

相关推荐
Eric_见嘉13 小时前
NestJS 🧑‍🍳 厨子必修课(九):API 文档 Swagger
前端·后端·nestjs
黑白极客13 小时前
怎么给字符串字段加索引?日志系统 一条更新语句是怎么执行的
java·数据库·sql·mysql·引擎
爬山算法13 小时前
Hibernate(32)什么是Hibernate的Criteria查询?
java·python·hibernate
码农水水13 小时前
中国邮政Java面试:热点Key的探测和本地缓存方案
java·开发语言·windows·缓存·面试·职场和发展·kafka
大厂技术总监下海13 小时前
数据湖加速、实时数仓、统一查询层:Apache Doris 如何成为现代数据架构的“高性能中枢”?
大数据·数据库·算法·apache
a程序小傲13 小时前
小红书Java面试被问:TCC事务的悬挂、空回滚问题解决方案
java·开发语言·人工智能·后端·python·面试·职场和发展
北辰alk13 小时前
2025:当Vibe Coding成为我的创意画布——一名前端工程师的AI元年记
前端·trae
短剑重铸之日14 小时前
《SpringBoot4.0初识》第五篇:实战代码
java·后端·spring·springboot4.0
heartbeat..14 小时前
Spring MVC 全面详解(Java 主流 Web 开发框架)
java·网络·spring·mvc·web
jump_jump14 小时前
SaaS 时代已死,SaaS 时代已来
前端·后端·架构