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

相关推荐
YA33319 分钟前
java基础(十)sql的mvcc
数据库
呼啦啦啦啦啦啦啦啦1 小时前
常见的排序算法
java·算法·排序算法
百万蹄蹄向前冲1 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
anlogic1 小时前
Java基础 8.18
java·开发语言
朝阳5812 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路2 小时前
GeoTools 读取影像元数据
前端
练习时长一年2 小时前
AopAutoConfiguration源码阅读
java·spring boot·intellij-idea
ssshooter3 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
源码宝3 小时前
【智慧工地源码】智慧工地云平台系统,涵盖安全、质量、环境、人员和设备五大管理模块,实现实时监控、智能预警和数据分析。
java·大数据·spring cloud·数据分析·源码·智慧工地·云平台
Jerry3 小时前
Jetpack Compose 中的状态
前端