一、应用场景:
- 根据实际业务动态创建队列发送消息并消费,队列名称无法提前确定
- 业务处理完成后删除对应队列,避免资源占用
- 分布式部署时,需要自动拉起其它节点的消费队列进行业务处理
二、功能设计及实现:
(1)设计流程
开始创建队列时首先判断队列是否存在,后续将通知发送至Notice队列通知其它节点此队列已创建开启
监听,消费完毕后删除队列,并发送队列删除信息至其它节点,停止监听。对于整个生产、监听过程中
产生的失败消息通过死信队列进行处理,后续对失败消息进行再次处理或入库记录
具体项目代码目录结构可按如下结构进行设计,描述信息如下:
- config:配置RabbitMq相关配置信息(预取数量、自动重连时间等等)
- controller:接口层(提供对外API接口)
- model:模型类(业务定义模型类)
- sender:mq发送消息业务(发送消息)
- handler:mq消费处理消息业务
- service:业务类
(2)核心方法
RabbitMqConfig完成消息队列相关信息配置。其主要配置项如下:
(1)设置预取数量、自动重连时间间隔
@Configuration
public class RabbitMqConfig {
@Bean
@Primary
public SimpleRabbitListenerContainerFactory proxyRabbitListenerContainerFactory(
ConnectionFactory connectionFactory,
SimpleRabbitListenerContainerFactoryConfigurer configurer) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setPrefetchCount(5); // 设置预取数量
factory.setRecoveryInterval(5000L); // 自动重连间隔时间
return factory;
}
}
(2)设置队列与消费处理类绑定
@Bean
public SimpleMessageListenerContainer userMessageListenerContainer(ConnectionFactory connectionFactory,
MessageListenerAdapter userListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(USER_QUEUE_NAME); // 设置要监听的队列名称
container.setMessageListener(userListenerAdapter);
container.setPrefetchCount(5);
container.setRecoveryInterval(5000L);
return container;
}
@Bean
public MessageListenerAdapter userListenerAdapter(UserHandlerWithMessage handler) {
return new MessageListenerAdapter(handler, "handleMessage");
}
(3)配置死信队列
// 定义死信交换机
@Bean
public DirectExchange deadLetterExchange() {
return new DirectExchange(DEAD_LETTER_EXCHANGE);
}
// 定义死信队列
@Bean
public Queue deadLetterQueue() {
return new Queue(DEAD_LETTER_QUEUE);
}
// 绑定死信队列到死信交换机
@Bean
public Binding deadLetterBinding() {
return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange(