springboot同时配置多个MQ

本文详细介绍了如何在Spring Boot应用中配置两个RabbitMQ数据源,通过不同的ConnectionFactory实例分别连接到两个独立的RabbitMQ服务器。文章展示了如何在application.properties文件中设置属性,并在RabbitConfig类中创建ConnectionFactory和RabbitTemplate实例。此外,还提供了监听器和发送者的实现,以展示如何在两个不同的MQ中进行消息的发送和接收。

配置2个数据源:

application.properties

# 第一个mq
spring.rabbitmq.first.host=${mq.host}
spring.rabbitmq.first.port=${mq.port}
spring.rabbitmq.first.username=${mq.username}
spring.rabbitmq.first.password=${mq.password}
spring.rabbitmq.first.virtualHost=${mq.vhost}

# 第二个mq
spring.rabbitmq.second.host=${rabbitmq.address}
spring.rabbitmq.second.port=${rabbitmq.port}
spring.rabbitmq.second.username=${rabbitmq.username}
spring.rabbitmq.second.password=${rabbitmq.password}
spring.rabbitmq.second.virtualHost=${rabbitmq.vhost}

配置MQ

RabbitConfig.java


import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.io.IOException;

@Configuration
public class RabbitConfig {

    @Bean(name = "firstConnectionFactory")
    @Primary
    public ConnectionFactory firstConnectionFactory(
            @Value("${spring.rabbitmq.first.host}") String host,
            @Value("${spring.rabbitmq.first.port}") int port,
            @Value("${spring.rabbitmq.first.username}") String username,
            @Value("${spring.rabbitmq.first.password}") String password,
            @Value("${spring.rabbitmq.first.virtualHost}") String virtualHost
    ) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        return connectionFactory;
    }

    @Bean(name = "secondConnectionFactory")
    public ConnectionFactory secondConnectionFactory(
            @Value("${spring.rabbitmq.second.host}") String host,
            @Value("${spring.rabbitmq.second.port}") int port,
            @Value("${spring.rabbitmq.second.username}") String username,
            @Value("${spring.rabbitmq.second.password}") String password,
            @Value("${spring.rabbitmq.second.virtualHost}") String virtualHost
    ) {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
        connectionFactory.setHost(host);
        connectionFactory.setPort(port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost(virtualHost);
        return connectionFactory;
    }

    @Bean(name = "firstRabbitTemplate")
    @Primary
    public RabbitTemplate firstRabbitTemplate(
            @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory
    ) {
        RabbitTemplate firstRabbitTemplate = new RabbitTemplate(connectionFactory);
        return firstRabbitTemplate;
    }

    @Bean(name = "secondRabbitTemplate")
    public RabbitTemplate secondRabbitTemplate(
            @Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory
    ) {
        RabbitTemplate secondRabbitTemplate = new RabbitTemplate(connectionFactory);
        return secondRabbitTemplate;
    }

    // 配置监听1
    @Bean(name = "firstFactory")
    public SimpleRabbitListenerContainerFactory firstFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory
    ) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    // 配置监听2
    @Bean(name = "secondFactory")
    public SimpleRabbitListenerContainerFactory secondFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            @Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory
    ) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }

    /* 创建队列hello1,
       因为这里没有指定connectFactory,所以使用的是默认的connectionFactory,
       即用@Primary标记的firstConnectionFactory创建的,所以下面这种写法只会再第一个默认的mq种创建队列
       注意:这一段并不会在第二个mq中创建队列hello1
     */
    @Bean
    public Queue firstQueue() {
        System.out.println("configuration firstQueue ........................");
        return new Queue("hello1");
    }



    /** 如果要在第二个mq中也创建队列hello1,那么需要指定数据源secondConnectionFactory **/
    @Bean
    public String chargeQueue(@Qualifier("secondConnectionFactory") ConnectionFactory connectionFactory) {
        try {
            connectionFactory.createConnection().createChannel(false).queueDeclare("hello1", true, false, false, null);
        }catch (IOException e){
            e.printStackTrace();
        }
        return "hello1";
    }
}


注意

这里注意上面创建队列的方式,创建队列时候,如果没有指定ConnectionFactory时,那么只会在默认的ConnectionFactory数据源MQ中创建队列,在其他的MQ中创建队列,需要指定ConnectionFactory

配置监听消费端

Listener1.java

import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "hello1", containerFactory="firstFactory")
public class Listener1 {

    @RabbitHandler
    public void process(String hello) {
        System.out.println("queue1-Receiver  : " + hello);
    }

}

Listener2.java

@Component
@RabbitListener(queues = "hello1", containerFactory="secondFactory")
public class Listener2 {

    @RabbitHandler
    public void process(String hello) {
        System.out.println("queue2-Receiver  : " + hello);
    }

}

模拟发送

Sender.java

import java.util.Date;
import javax.annotation.Resource;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

@Component
public class Sender {

 @Resource(name="firstRabbitTemplate")
 private RabbitTemplate firstRabbitTemplate;

 public void send1() {
  String context = "quene1:hello1 " + new Date();
  System.out.println("Sender : " + context);
  this.firstRabbitTemplate.convertAndSend("hello1", context);
 }

}

Sender2.java

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;

@Component
public class Sender2 {

 @Resource(name="secondRabbitTemplate")
 private RabbitTemplate secondRabbitTemplate;

 public void send1() {
  String context = "quene2:hello1 " + new Date();
  System.out.println("Sender : " + context);
  this.secondRabbitTemplate.convertAndSend("hello1", context);
 }

}

测试

TestDemo01.java

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class TestDemo01 {

 @Autowired
 private Sender sender;

 @Autowired
 private Sender2 sender2;


 @Test
 public void hello() throws Exception {
  sender.send1();
 }

 @Test
 public void hello2() throws Exception {
  sender2.send1();
 }
}


<think>首先,用户的问题是关于Spring Boot如何对接多个MQ服务的方法。我需要基于提供的引用材料来回答。 回顾引用: - 引用[1]讨论了在整合MQ时遇到的问题,比如项目自动连接本地MQ,原因是springbootadmin启用了MQ健康检查。解决方案是关闭admin配置中的MQ健康检查。 - 引用[2]展示了快速整合MQ的依赖:spring-boot-starter-amqp。 - 引用[3]提供了一个Java示例,展示了如何使用RabbitMQ接收消息。 - 引用[4]提到在Spring Cloud Alibaba项目中集成RocketMQ,作为一个队列模型的消息中间件。 - 引用[5]讨论了Spring Boot对接多个MQ并实现延迟队列,提到了使用@RabbitListener时指定ListenerContainerFactory。 用户的核心问题是:"我想查找Spring Boot对接多个MQ服务的方法 请问Spring Boot对接多个MQ服务的实现方案"。所以,我需要给出一个清晰的实现方案。 关键点: - Spring Boot支持多个MQ服务,如RabbitMQ、RocketMQ等。 - 引用[5]直接提到了"springBoot对接多个mq",并指定了使用@RabbitListener时指定不同的ListenerContainerFactory来区分MQ实例。 实现方案步骤: 1. **添加依赖**:对于每个MQ类型,添加相应的Spring Boot starter。例如,对于RabbitMQ,添加spring-boot-starter-amqp;对于RocketMQ,添加相关依赖(如在引用[4]中提到的Spring Cloud Alibaba集成)。 2. **配置多个MQ实例**:在application.yml或application.properties中,为每个MQ实例定义配置。使用不同的profile或前缀来区分。 3. **创建自定义的ConnectionFactory**:针对每个MQ实例,创建自定义的连接工厂。例如,对于RabbitMQ,创建RabbitConnectionFactory。 4. **定义RabbitTemplate和RabbitListenerContainerFactory**:为每个MQ实例创建这些bean,指定不同的连接工厂。 5. **使用@RabbitListener**:在消费者端,使用@RabbitListener注解时,指定containerFactory属性来关联到特定的MQ实例。 从引用[5]:"后续使用注解@RabbitListener 时指定ListenerContainerFactory @RabbitListener(queues = DEAD_LETTER_QUEUE_B, containerFactory = "masterListenerContainerFactory")",这显示了如何通过指定containerFactory来区分不同的MQ连接。 另外,引用[1]提到的问题是关于项目自动连接本地MQ,原因是由springbootadmin触发的健康检查,解决方案是关闭MQ健康检查。这可能在配置多个MQ时需要处理,以避免类似的意外连接。 结构回答: - 回答应该清晰、步骤化。 - 使用系统级指令:行内数学表达式用$...$,但这里可能不涉及数学公式;独立公式用$$...$$,同样可能不适用;使用中文;生成相关问题;在引用的末尾添加引用标识。 生成相关问题: - 基于主题,生成3-4个相关问题,如: 1. 如何配置Spring Boot以支持RabbitMQ和RocketMQ同时使用? 2. 如何避免Spring Boot启动时自动连接默认MQ? 3. 如何使用@RabbitListener指定不同的MQ实例? 4. 如何处理多个MQ的健康检查问题? 确保回答真实可靠:基于引用材料,避免引入外部知识。 最终回答结构: 1. 简要介绍实现方案。 2. 详细步骤。 3. 生成相关问题。 </think>基于提供的引用材料,我将为您详细解释 Spring Boot 对接多个 MQ 服务的实现方案。此方案支持同时集成多个 MQ 实例(如 RabbitMQ、RocketMQ 等),核心是通过自定义配置和注解来区分不同 MQ 连接。参考引用[5]中的关键点,方案利用 `@RabbitListener` 指定不同的 `ListenerContainerFactory` 实现多实例管理。 ### Spring Boot 对接多个 MQ 服务的实现方案 #### 1. **添加依赖** 在 `pom.xml` 中添加所需 MQ 的 Spring Boot starter 依赖。例如: - RabbitMQ 依赖(参考引用[2]): ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` - RocketMQ 依赖(参考引用[4]): ```xml <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>2.2.0</version> <!-- 版本根据实际调整 --> </dependency> ``` 如果同时使用多个 MQ 类型,需添加所有相关依赖。确保依赖版本兼容您的 Spring Boot 版本。 #### 2. **配置多个 MQ 实例** 在 `application.yml` 中定义不同 MQ 实例的配置,使用自定义前缀区分: ```yaml # RabbitMQ 主实例配置 rabbitmq: master: host: master.mq.server port: 5672 username: admin password: master_pass slave: host: slave.mq.server port: 5672 username: user password: slave_pass # RocketMQ 配置(参考引用[4]) rocketmq: name-server: rocketmq.server:9876 producer: group: producer_group ``` 此配置允许您为 RabbitMQ 定义多个实例(如主备),并为其他 MQ 如 RocketMQ 单独设置。 #### 3. **创建自定义连接工厂和容器工厂** 为每个 MQ 实例创建 `ConnectionFactory` 和 `RabbitListenerContainerFactory` bean: ```java import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MQConfig { // 主 RabbitMQ 实例的 ConnectionFactory @Bean public CachingConnectionFactory masterConnectionFactory() { CachingConnectionFactory factory = new CachingConnectionFactory(); factory.setHost("master.mq.server"); // 从配置读取 factory.setUsername("admin"); factory.setPassword("master_pass"); return factory; } // 从 RabbitMQ 实例的 ConnectionFactory @Bean public CachingConnectionFactory slaveConnectionFactory() { CachingConnectionFactory factory = new CachingConnectionFactory(); factory.setHost("slave.mq.server"); factory.setUsername("user"); factory.setPassword("slave_pass"); return factory; } // 为主实例创建 ListenerContainerFactory(参考引用[5]) @Bean(name = "masterListenerContainerFactory") public SimpleRabbitListenerContainerFactory masterListenerContainerFactory() { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(masterConnectionFactory()); return factory; } // 为从实例创建 ListenerContainerFactory @Bean(name = "slaveListenerContainerFactory") public SimpleRabbitListenerContainerFactory slaveListenerContainerFactory() { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(slaveConnectionFactory()); return factory; } } ``` 此步骤确保每个 MQ 实例有独立的连接池和监听容器。 #### 4. **编写消费者代码** 在消费者类中使用 `@RabbitListener` 注解,通过 `containerFactory` 属性指定目标 MQ 实例: ```java import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class MQConsumer { // 监听主 MQ 实例的队列 @RabbitListener(queues = "MASTER_QUEUE", containerFactory = "masterListenerContainerFactory") public void handleMasterMessage(String message) { System.out.println("主 MQ 接收到消息: " + message); } // 监听从 MQ 实例的队列 @RabbitListener(queues = "SLAVE_QUEUE", containerFactory = "slaveListenerContainerFactory") public void handleSlaveMessage(String message) { System.out.println("从 MQ 接收到消息: " + message); } } ``` 此做法允许消息路由到指定 MQ 实例(参考引用[5]的实现思路)。 #### 5. **处理常见问题** - **避免自动连接默认 MQ**:如果项目启动时意外连接本地 MQ(如引用[1]所述),可能是健康检查触发。需在 `application.yml` 禁用健康检查: ```yaml management: health: rabbit: enabled: false # 关闭 RabbitMQ 健康检查 ``` 或在 Spring Boot Admin 配置中排除 MQ 检查。 - **测试与发送消息**:使用 `RabbitTemplate` 发送消息时,同样需要指定连接工厂: ```java @Autowired private RabbitTemplate masterRabbitTemplate; // 注入自定义的 RabbitTemplate ``` #### 6. **测试与部署** 启动服务后,通过 API 或 MQ 管理页面发送测试数据(参考引用[1])。确保控制台正确接收不同 MQ 实例的消息。移植到正式项目时,验证配置无误以避免意外连接[^1]。 ### 关键注意事项 - **支持其他 MQ**:对于 RocketMQ(引用[4]),需创建 `RocketMQTemplate` bean 并指定 name-server。 - **性能与可靠性**:在大并发场景下,为每个 MQ 实例配置连接池大小(参考引用[5])。 - **监控与调试**:启用 Spring Boot Actuator 监控 MQ 状态,但确保健康检查配置正确[^1]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EmineWang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值