文章目录
在电商平台中,订单生成后如果长时间未被处理,我们通常需要自动取消这些订单。这种需求不仅能够提升用户体验,还能有效管理库存和资源分配。而如何实现这一需求,延迟消息队列无疑是一个高效的解决方案。今天,我们就来聊聊如何使用 Redisson 实现一个简洁且强大的延迟消息处理机制。
一、发送延迟消息:定时触发订单取消
首先,我们需要在生成订单之后,立即发送一个延迟消息。在这个方法中,我们使用了 Redisson 的 RBlockingQueue
和 RDelayedQueue
来实现消息的延迟发送。
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 实现延迟消息队列是一种高效的订单管理策略。通过这种方式,我们不仅能够精确地控制订单的处理时效,还可以大幅提升系统的稳定性和响应速度。同时,这种实现方式相对简单,易于维护和扩展。