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

相关推荐
Java开发追求者6 分钟前
npm镜像源证书过期的问题解决
前端·npm·node.js·npm镜像源证书过期的问题解决
Ty_110612 分钟前
深入理解Java虚拟机:Jvm总结-虚拟机字节码执行引擎
java·开发语言·jvm
宝子向前冲15 分钟前
React中九大常用Hooks总结
前端·javascript·react.js
阿维的博客日记16 分钟前
简要介绍联合索引
数据库·联合索引
夜夜亮晶晶25 分钟前
MySQL——数据类型(一)
数据库·mysql
小白小白从不日白30 分钟前
react 基础语法
前端·react.js
岸边的风30 分钟前
前端Excel热成像数据展示及插值算法
前端·算法·excel
蔚一34 分钟前
Java设计模式—面向对象设计原则(一) ----->开闭原则OCP(完整详解,附有代码+案例)
java·后端·设计模式·intellij-idea·开闭原则
cesske40 分钟前
java 学习从零到精通之历程
java
爱吃香蕉的猴哥42 分钟前
Spring AOP
java·后端·spring