refactor: 订单超时关单死信队列优化至公共模块

This commit is contained in:
郝先瑞 2022-02-04 23:39:26 +08:00
parent 2eb931ac62
commit 0827302f4c
5 changed files with 106 additions and 94 deletions

View File

@ -1,76 +0,0 @@
package com.youlai.mall.oms.config;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
* @author huawei
* @email huawei_code@163.com
* @date 2021/1/17
* @desc 业务描述
* 1. 订单创建成功发送消息到创建订单的路由
* 2. 创建订单的路由转发消息给延时队列延时队列的延时时间就是订单从创建到支付过程允许的最大等待时间延时队列不能有消费者即消息不能被消费
* 3. 延时时间一到消息被转入DLX死信路由
* 4. 死信路由把死信消息转发给死信队列
* 5. 订单系统监听死信队列获取到死信消息后执行关单解库存操作
*/
@Configuration
@Slf4j
@AllArgsConstructor
public class RabbitMQConfig {
/**
* 定义交换机订单业务统一使用 order.exchange 交换机
*/
@Bean
public Exchange exchange() {
return new TopicExchange("order.exchange", true, false);
}
/**
* 延时队列超时会通过交换机和路由key转发到死信队列没有消费者
*/
@Bean
public Queue delayQueue() {
// 延时队列的消息过期了会自动触发消息的转发根据routingKey发送到指定的exchange中exchange路由到死信队列
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "order.exchange");
args.put("x-dead-letter-routing-key", "order.close"); // 死信路由Key
args.put("x-message-ttl", 60000); // 单位毫秒1分钟测试使用
return new Queue("order.delay.queue", true, false, false, args);
}
/**
* 延时队列绑定交换机路由键order.create
* 订单提交时会发送routingKey=order.create.order的消息至exchange然后会被路由到上面的delayQueue延时队列延时队列没有消费者到期后会将消息转发
*/
@Bean
public Binding delayQueueBinding() {
return new Binding("order.delay.queue", Binding.DestinationType.QUEUE,"order.exchange","order.create",null);
}
/**
* 死信队列普通队列
*/
@Bean
public Queue closeOrderQueue() {
return new Queue("order.close.queue", true, false, false);
}
/**
* 死信队列绑定交换机
* 其中死信路由的routingKey=order.close和延时队列的routingKey一致延时队列过期时将消息发送给exchangeexchange再路由到死信队列
*/
@Bean
public Binding closeOrderQueueBinding() {
return new Binding("order.close.queue", Binding.DestinationType.QUEUE,"order.exchange","order.close",null);
}
}

View File

@ -0,0 +1,28 @@
package com.youlai.common.rabbitmq.config;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author huawei
* @desc
* @email huawei_code@163.com
* @date 2021/1/17
*/
@Configuration
@EnableTransactionManagement
public class RabbitMQConfig {
/**
* 使用json序列化机制进行消息转换
*
* @return
*/
@Bean
public MessageConverter jackson2MessageConverter() {
return new Jackson2JsonMessageConverter();
}
}

View File

@ -1,17 +0,0 @@
package com.youlai.common.rabbitmq.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author huawei
* @desc
* @email huawei_code@163.com
* @date 2021/1/17
*/
@Configuration
@EnableTransactionManagement
public class RabbitMqConfig {
}

View File

@ -0,0 +1,76 @@
package com.youlai.common.rabbitmq.queue;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
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.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* 订单超时关单死信队列
*
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
* @date 2022/2/4 23:21
*/
@Component
@ConditionalOnProperty(prefix = "spring.application.name", value = "mall-oms")
@Slf4j
public class OrderCloseQueue {
/**
* 定义交换机
*/
@Bean
public Exchange orderExchange() {
return new TopicExchange("order.exchange", true, false);
}
/**
* 延时队列
*/
@Bean
public Queue orderDelayQueue() {
log.info("延时队列(order.delay.queue)创建");
// 延时队列的消息过期了会自动触发消息的转发根据routingKey发送到指定的exchange中exchange路由到死信队列
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "order.exchange");
args.put("x-dead-letter-routing-key", "order.close"); // 死信路由Key
args.put("x-message-ttl", 60000); // 单位毫秒1分钟测试使用
return new Queue("order.delay.queue", true, false, false, args);
}
/**
* 延时队列绑定交换机
*/
@Bean
public Binding orderDelayQueueBinding() {
return new Binding("order.delay.queue", Binding.DestinationType.QUEUE,"order.exchange","order.create",null);
}
/**
* 死信队列
*/
@Bean
public Queue orderCloseQueue() {
log.info("死信队列(order.close.queue)创建");
return new Queue("order.close.queue", true, false, false);
}
/**
* 死信队列绑定交换机
*/
@Bean
public Binding orderCloseQueueBinding() {
return new Binding("order.close.queue", Binding.DestinationType.QUEUE,"order.exchange","order.close",null);
}
}

View File

@ -1,2 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.youlai.common.rabbitmq.config.RabbitMqConfig
com.youlai.common.rabbitmq.config.RabbitMQConfig,\
com.youlai.common.rabbitmq.queue.OrderCloseQueue