RabbitMQ使用延迟消息
1.什么情况下使用延迟消息
延迟消息 适用于需要在一段时间后执行某些操作的场景,常见的有以下几类:
1.1. 订单超时取消(未支付自动取消)
场景 : 用户下单后,如果 30 分钟内未付款,系统需要自动取消订单。
实现方式:
-
订单创建时,发送延迟消息 ,30 分钟后检查订单状态。
-
若订单仍未支付,则自动取消 并释放库存。
2.支付后延迟发货 🚚
场景 : 某些商品需要延迟发货 ,例如 7 天无理由退款期间不立即发货,等待用户是否申请退款。
实现方式:
-
用户付款后,发送延迟消息 ,7 天后检查订单状态。
-
如果用户未申请退款,则发货;否则取消发货。
3. 限时活动(抢购、秒杀等) ⏳
场景 : 某些促销活动(如秒杀、限时抢购)在特定时间开始或结束。
实现方式:
-
活动开始 前,发送延迟消息,定时开放库存。
-
活动结束 前,发送延迟消息,下架商品,停止抢购。
2.延迟消息实现
这里使用第一种情况实现(下单未付款,特定时间内取消订单,恢复库存)
1.下载RabbitMQ的延迟消息插件,地址:
Releases · rabbitmq/rabbitmq-delayed-message-exchange
下载完将插件在docker中添加到RabbitMQ的plugins中,然后docker restart rabbitmq重启RabbitMQ
2.在交换机中添加新的交换机,类型中多了一个x-delayed-message,这表示延迟消息插件安装成功
3.使用注解声明延迟消息交换机
定义远驰消息交换机名字、延迟消息队列和routingkey
java
public interface MqConstants {
String DELAY_EXCHANGE_NAME = "trade.delay.direct";
String DELAY_ORDER_QUEUE_NAME = "trade.delay.order.queue";
String DELAY_ORDER_KEY = "delay.order.query";
}
java
/**
* 监听延迟队列,如果订单下单未支付,则取消订单,恢复库存
* @param orderId
*/
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = MqConstants.DELAY_ORDER_QUEUE_NAME), //延迟队列名
exchange = @Exchange(name = MqConstants.DELAY_EXCHANGE_NAME, delayed = "true"), //延迟交换机名
key = MqConstants.DELAY_ORDER_KEY //routingkey
))
public void listenOrderDelayMessage(Long orderId){
// 1.查询订单
Order order = orderService.getById(orderId);
// 2.检测订单状态,判断是否已支付
if(order == null || order.getStatus() != 1){
// 订单不存在或者已经支付
return;
}
// 3.未支付,需要查询支付流水状态
PayOrderDTO payOrder = payClient.queryPayOrderByBizOrderNo(orderId);
// 4.判断是否支付
if(payOrder != null && payOrder.getStatus() == 3){
// 4.1.已支付,标记订单状态为已支付
orderService.markOrderPaySuccess(orderId);
}else{
// TODO 4.2.未支付,取消订单,回复库存
System.out.println("订单未支付,取消订单,回复库存");
// orderService.cancelOrder(orderId);
}
}
}
4.发送消息
用户下单完毕后,想延迟消息队列发送消息
java
//下单完毕后
/**
* TODO:发送延迟消息,查询10秒后订单的状态,如果没支付,则取消订单,恢复库存
*/
rabbitTemplate.convertAndSend(
MqConstants.DELAY_EXCHANGE_NAME,
MqConstants.DELAY_ORDER_KEY,
order.getId(),
message -> {
message.getMessageProperties().setDelay(1000 * 10);//延迟时间10s
return message;
}
);
通过设置交换机名字和routingkey可以绑定到延迟消息队列
这里设置延迟时间为10s(方便测试),下单10s后会发送消息到延迟消息交换机,然后去判断用户是否支付,如果未支付,则取消订单恢复库存
3.实践
发送下单请求

控制台可以看到,下单到消费消息中间间隔十秒钟,表明我们设置的延迟消息成功
