添加rabbitmq延迟队列插件处理订单超时功能

This commit is contained in:
2025-07-01 07:18:02 +08:00
parent 097bbb9b55
commit bca95d683d
6 changed files with 122 additions and 1 deletions

View File

@ -0,0 +1,17 @@
package com.greenorange.promotion.constant;
import java.util.List;
public interface MqConstant {
List<Long> DELAY_MILLIS = List.of(10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 120000L, 120000L, 300000L);
// List<Long> DELAY_MILLIS = List.of(10000L, 10000L, 10000L, 15000L, 15000L);
String DELAY_EXCHANGE = "delay.topic";
String DELAY_ORDER_QUEUE = "order.delay.queue";
String DELAY_ORDER_ROUTING_KEY = "order.key";
}

View File

@ -78,6 +78,8 @@ public class CourseOrderController {
courseOrder.setTotalAmount(course.getDiscountPrice()); courseOrder.setTotalAmount(course.getDiscountPrice());
courseOrder.setUserId(userId); courseOrder.setUserId(userId);
courseOrderService.save(courseOrder); courseOrderService.save(courseOrder);
// 向消息队列中发送订单创建的消息
courseOrderService.sendCreateOrderMessage(courseOrder.getId());
return ResultUtils.success(courseOrder.getId()); return ResultUtils.success(courseOrder.getId());
} }

View File

@ -0,0 +1,66 @@
package com.greenorange.promotion.listener;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.greenorange.promotion.constant.MqConstant;
import com.greenorange.promotion.constant.OrderStatusConstant;
import com.greenorange.promotion.model.entity.CourseOrder;
import com.greenorange.promotion.service.course.CourseOrderService;
import com.greenorange.promotion.utils.MultiDelayMessage;
import jakarta.annotation.Resource;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
@Component
public class OrderStatusListener {
@Resource
private CourseOrderService courseOrderService;
@Resource
private RabbitTemplate rabbitTemplate;
@RabbitListener(bindings = @QueueBinding(
value = @Queue(MqConstant.DELAY_ORDER_QUEUE),
exchange = @Exchange(name = MqConstant.DELAY_EXCHANGE, delayed = "true"),
key = MqConstant.DELAY_ORDER_ROUTING_KEY
))
public void listenDelayMessage(MultiDelayMessage<Long> msg) {
System.out.println("\n\n\n\n\nOrderStatusListener.listenerDelayMessage msg-------------------------------->" + msg);
// 1.获取消息中的订单id
Long orderId = msg.getData();
// 2.查询订单,判断状态是否为待支付
CourseOrder courseOrder = courseOrderService.getById(orderId);
// 订单不存在或者订单已经支付
if (courseOrder == null || !courseOrder.getOrderStatus().equals(OrderStatusConstant.PENDING)) {
return ;
}
// 3.订单未支付,判断是否还有剩余延时时间
if (msg.hasNextDelay()) {
// 有延迟时间需要重发延迟消息先获取延迟时间的int值
// 发送延时消息
Long delayValue = msg.removeNextDelay();
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
MqConstant.DELAY_ORDER_ROUTING_KEY, msg, message -> {
// 添加延迟消息属性
message.getMessageProperties().setDelayLong(delayValue);
return message;
});
return ;
}
// 没有剩余延时时间,说明订单超时未支付,需取消订单
LambdaUpdateWrapper<CourseOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(CourseOrder::getId, orderId)
.set(CourseOrder::getOrderStatus, OrderStatusConstant.CLOSED);
courseOrderService.updateById(courseOrder);
}
}

View File

@ -17,4 +17,10 @@ public interface CourseOrderService extends IService<CourseOrder> {
* 获取查询条件 * 获取查询条件
*/ */
QueryWrapper<CourseOrder> getQueryWrapper(CourseOrderQueryRequest courseOrderQueryRequest); QueryWrapper<CourseOrder> getQueryWrapper(CourseOrderQueryRequest courseOrderQueryRequest);
/**
* 向消息队列中发送订单创建的消息
*/
void sendCreateOrderMessage(Long orderId);
} }

View File

@ -3,14 +3,21 @@ package com.greenorange.promotion.service.course.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.greenorange.promotion.constant.CommonConstant; import com.greenorange.promotion.constant.CommonConstant;
import com.greenorange.promotion.constant.MqConstant;
import com.greenorange.promotion.model.dto.courseOrder.CourseOrderQueryRequest; import com.greenorange.promotion.model.dto.courseOrder.CourseOrderQueryRequest;
import com.greenorange.promotion.model.entity.CourseOrder; import com.greenorange.promotion.model.entity.CourseOrder;
import com.greenorange.promotion.service.course.CourseOrderService; import com.greenorange.promotion.service.course.CourseOrderService;
import com.greenorange.promotion.mapper.CourseOrderMapper; import com.greenorange.promotion.mapper.CourseOrderMapper;
import com.greenorange.promotion.utils.MultiDelayMessage;
import com.greenorange.promotion.utils.SqlUtils; import com.greenorange.promotion.utils.SqlUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/** /**
* @author 35880 * @author 35880
* @description 针对表【course_order(课程订单表)】的数据库操作Service实现 * @description 针对表【course_order(课程订单表)】的数据库操作Service实现
@ -21,6 +28,10 @@ public class CourseOrderServiceImpl extends ServiceImpl<CourseOrderMapper, Cours
implements CourseOrderService{ implements CourseOrderService{
@Resource
private RabbitTemplate rabbitTemplate;
/** /**
* 获取查询条件 * 获取查询条件
*/ */
@ -36,6 +47,25 @@ public class CourseOrderServiceImpl extends ServiceImpl<CourseOrderMapper, Cours
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField); queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
return queryWrapper; return queryWrapper;
} }
/**
* 向消息队列中发送订单创建的消息
*/
@Override
public void sendCreateOrderMessage(Long orderId) {
// 复制 DELAY_MILLIS 到一个新的 ArrayList
List<Long> newDelayMillis = new ArrayList<>(MqConstant.DELAY_MILLIS);
// 延迟检查订单状态信息
MultiDelayMessage<Long> msg = new MultiDelayMessage<>(orderId, newDelayMillis);
long delayValue = msg.removeNextDelay();
rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE,
MqConstant.DELAY_ORDER_ROUTING_KEY, msg, message -> {
// 添加延迟消息属性
message.getMessageProperties().setDelayLong(delayValue);
return message;
});
}
} }

View File

@ -1,4 +1,4 @@
spring: spring:
profiles: profiles:
active: test active: dev