refactor(mall-oms): 订单超时未支付定时关闭订单的死信队列调整根据配置动态创建、绑定交换机和队列

This commit is contained in:
郝先瑞 2022-04-05 22:14:46 +08:00
parent 4a4ee3d9aa
commit c7bb7d206f
7 changed files with 36 additions and 45 deletions

View File

@ -27,7 +27,6 @@ public class OrderSubmitForm {
*/ */
private Long totalAmount; private Long totalAmount;
/** /**
* 支付金额(单位) * 支付金额(单位)
*/ */
@ -38,9 +37,9 @@ public class OrderSubmitForm {
*/ */
private List<OrderItemDTO> orderItems; private List<OrderItemDTO> orderItems;
// 收货地址 /**
* 订单备注
*/
@Size(max = 500, message = "订单备注长度不能超过500") @Size(max = 500, message = "订单备注长度不能超过500")
private String remark; private String remark;
@ -49,7 +48,6 @@ public class OrderSubmitForm {
*/ */
private String couponId; private String couponId;
/** /**
* 收获地址 * 收获地址
*/ */

View File

@ -191,7 +191,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
result = orderItemService.saveBatch(saveOrderItems); result = orderItemService.saveBatch(saveOrderItems);
if (result) { if (result) {
// 订单超时取消 // 订单超时取消
rabbitTemplate.convertAndSend("order.exchange", "order.create", orderToken); rabbitTemplate.convertAndSend("order.exchange", "order.create.routing.key", orderToken);
} }
} }
Assert.isTrue(result, "订单提交失败"); Assert.isTrue(result, "订单提交失败");

View File

@ -15,6 +15,6 @@ public class RabbitMQTest {
@Test @Test
public void createOrderTest() { public void createOrderTest() {
rabbitTemplate.convertAndSend("order.exchange", "order.create", "4acd475a-c6aa-4d9a-a3a5-40da7472cbee"); rabbitTemplate.convertAndSend("order.exchange", "order.create.routing.key", "4acd475a-c6aa-4d9a-a3a5-40da7472cbee");
} }
} }

View File

@ -55,11 +55,6 @@ public class RabbitModuleInfo {
*/ */
private boolean autoDelete = false; // 默认false不自动删除 private boolean autoDelete = false; // 默认false不自动删除
/**
* 是否延迟交换机
*/
private boolean delayed;
/** /**
* 交换机其他参数 * 交换机其他参数
*/ */
@ -96,16 +91,12 @@ public class RabbitModuleInfo {
/** /**
* 绑定死信队列的交换机名称 * 绑定死信队列的交换机名称
*/ */
private String deadExchangeName; private String deadLetterExchange;
/** /**
* 绑定死信队列的路由key * 绑定死信队列的路由key
*/ */
private String deadRoutingKey; private String deadLetterRoutingKey;
private Long messageTtl;
private Map<String, Object> arguments; private Map<String, Object> arguments;

View File

@ -1,6 +1,7 @@
package com.youlai.common.rabbitmq.dynamic; package com.youlai.common.rabbitmq.dynamic;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -31,14 +32,14 @@ public class RabbitModuleInitializer implements SmartInitializingSingleton {
@Override @Override
public void afterSingletonsInstantiated() { public void afterSingletonsInstantiated() {
log.info("初始化 RabbitMQ 队列、交换机和绑定关系"); log.info("RabbitMQ 根据配置动态创建和绑定队列、交换机");
initRabbitModule(); declareRabbitModule();
} }
/** /**
* 初始化 RabbitMQ 队列交换机和绑定关系 * RabbitMQ 根据配置动态创建和绑定队列交换机
*/ */
private void initRabbitModule() { private void declareRabbitModule() {
List<RabbitModuleInfo> rabbitModuleInfos = rabbitModuleProperties.getModules(); List<RabbitModuleInfo> rabbitModuleInfos = rabbitModuleProperties.getModules();
if (CollectionUtil.isEmpty(rabbitModuleInfos)) { if (CollectionUtil.isEmpty(rabbitModuleInfos)) {
return; return;
@ -47,9 +48,9 @@ public class RabbitModuleInitializer implements SmartInitializingSingleton {
configParamValidate(rabbitModuleInfo); configParamValidate(rabbitModuleInfo);
// 队列 // 队列
Queue queue = convertToQueue(rabbitModuleInfo.getQueue()); Queue queue = convertQueue(rabbitModuleInfo.getQueue());
// 交换机 // 交换机
Exchange exchange = convertToExchange(rabbitModuleInfo.getExchange()); Exchange exchange = convertExchange(rabbitModuleInfo.getExchange());
// 绑定关系 // 绑定关系
String routingKey = rabbitModuleInfo.getRoutingKey(); String routingKey = rabbitModuleInfo.getRoutingKey();
String queueName = rabbitModuleInfo.getQueue().getName(); String queueName = rabbitModuleInfo.getQueue().getName();
@ -88,19 +89,25 @@ public class RabbitModuleInitializer implements SmartInitializingSingleton {
* @param queue * @param queue
* @return * @return
*/ */
public Queue convertToQueue(RabbitModuleInfo.Queue queue) { public Queue convertQueue(RabbitModuleInfo.Queue queue) {
Map<String, Object> arguments = queue.getArguments(); Map<String, Object> arguments = queue.getArguments();
// 是否需要绑定死信队列 // 转换ttl的类型为long
String deadExchangeName = queue.getDeadExchangeName(); if (arguments != null && arguments.containsKey("x-message-ttl")) {
String deadRoutingKey = queue.getDeadRoutingKey(); arguments.put("x-message-ttl", Convert.toLong(arguments.get("x-message-ttl")));
if (StrUtil.isNotBlank(deadExchangeName) && StrUtil.isNotBlank(deadRoutingKey)) { }
if (arguments != null) { // 是否需要绑定死信队列
String deadLetterExchange = queue.getDeadLetterExchange();
String deadLetterRoutingKey = queue.getDeadLetterRoutingKey();
if (StrUtil.isNotBlank(deadLetterExchange) && StrUtil.isNotBlank(deadLetterRoutingKey)) {
if (arguments == null) {
arguments = new HashMap<>(4); arguments = new HashMap<>(4);
arguments.put("x-dead-letter-exchange", deadExchangeName);
arguments.put("x-dead-letter-routing-key", deadRoutingKey);
} }
arguments.put("x-dead-letter-exchange", deadLetterExchange);
arguments.put("x-dead-letter-routing-key", deadLetterRoutingKey);
} }
return new Queue(queue.getName(), queue.isDurable(), queue.isExclusive(), queue.isAutoDelete(), arguments); return new Queue(queue.getName(), queue.isDurable(), queue.isExclusive(), queue.isAutoDelete(), arguments);
@ -113,7 +120,7 @@ public class RabbitModuleInitializer implements SmartInitializingSingleton {
* @param exchangeInfo * @param exchangeInfo
* @return * @return
*/ */
public Exchange convertToExchange(RabbitModuleInfo.Exchange exchangeInfo) { public Exchange convertExchange(RabbitModuleInfo.Exchange exchangeInfo) {
AbstractExchange exchange = null; AbstractExchange exchange = null;
@ -140,7 +147,6 @@ public class RabbitModuleInitializer implements SmartInitializingSingleton {
break; break;
} }
exchange.setDelayed(exchangeInfo.isDelayed());
return exchange; return exchange;
} }

View File

@ -1,10 +1,7 @@
package com.youlai.common.rabbitmq.queue; package com.youlai.common.rabbitmq.queue;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.*;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -18,8 +15,8 @@ import java.util.Map;
* @author <a href="mailto:xianrui0365@163.com">haoxr</a> * @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @date 2022/2/4 23:21 * @date 2022/2/4 23:21
*/ */
@Component
@ConditionalOnProperty(prefix = "spring.application.name", value = "mall-oms") @Deprecated
@Slf4j @Slf4j
public class OrderCloseQueue { public class OrderCloseQueue {
@ -28,7 +25,7 @@ public class OrderCloseQueue {
*/ */
@Bean @Bean
public Exchange orderExchange() { public Exchange orderExchange() {
return new TopicExchange("order.exchange", true, false); return new DirectExchange("order.exchange", true, false);
} }
/** /**
@ -40,7 +37,7 @@ public class OrderCloseQueue {
// 延时队列的消息过期了会自动触发消息的转发根据routingKey发送到指定的exchange中exchange路由到死信队列 // 延时队列的消息过期了会自动触发消息的转发根据routingKey发送到指定的exchange中exchange路由到死信队列
Map<String, Object> args = new HashMap<>(); Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "order.exchange"); args.put("x-dead-letter-exchange", "order.exchange");
args.put("x-dead-letter-routing-key", "order.close"); // 死信路由Key args.put("x-dead-letter-routing-key", "order.close.routing.key"); // 死信路由Key
args.put("x-message-ttl", 60 * 1000L); // 单位毫秒1分钟测试使用 args.put("x-message-ttl", 60 * 1000L); // 单位毫秒1分钟测试使用
return new Queue("order.delay.queue", true, false, false, args); return new Queue("order.delay.queue", true, false, false, args);
} }
@ -51,7 +48,7 @@ public class OrderCloseQueue {
*/ */
@Bean @Bean
public Binding orderDelayQueueBinding() { public Binding orderDelayQueueBinding() {
return new Binding("order.delay.queue", Binding.DestinationType.QUEUE,"order.exchange","order.create",null); return new Binding("order.delay.queue", Binding.DestinationType.QUEUE, "order.exchange", "order.create.routing.key", null);
} }
@ -69,7 +66,7 @@ public class OrderCloseQueue {
*/ */
@Bean @Bean
public Binding orderCloseQueueBinding() { public Binding orderCloseQueueBinding() {
return new Binding("order.close.queue", Binding.DestinationType.QUEUE,"order.exchange","order.close",null); return new Binding("order.close.queue", Binding.DestinationType.QUEUE, "order.exchange", "order.close.routing.key", null);
} }
} }

View File

@ -1,4 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.youlai.common.rabbitmq.config.RabbitConfig,\ com.youlai.common.rabbitmq.config.RabbitConfig,\
com.youlai.common.rabbitmq.queue.OrderCloseQueue,\
com.youlai.common.rabbitmq.dynamic.RabbitModuleProperties com.youlai.common.rabbitmq.dynamic.RabbitModuleProperties