springboot应用中rabbitmq consume多个集群或者vhost的信息

  今天项目遇到一个问题,同一个应用中,需要消费不同的vhost中不同queue的消息,目前只实现了multi consumer,如果还需要向不同的集群或vhost发消息,那么应该需要配置不同的RabbitAdmin,不知道有没有坑。

rabbit的大概配置如下:

1. 起初项目只需要监听一个vhost中的queue,所以使用spring-boot-autoconfigure中的默认配置,直接在config文件中配置:

spring.rabbitmq.host = mq-demo.sl.com
spring.rabbitmq.password = dangerous
spring.rabbitmq.port = 5672
spring.rabbitmq.username = admin
spring.rabbitmq.virtual-host = /msgbu

在rabbit的config文件中,只需要设置一下messageconverter即可,代码如下:

@Configuration
@ComponentScan
@Slf4j
public class RabbitMqConfig {

  @Bean(name = "xxxListenerContainer")
  public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactoryPlus(
      SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory,
      Jackson2JsonMessageConverter jackson2JsonMessageConverter) {
    rabbitListenerContainerFactory.setMessageConverter(jackson2JsonMessageConverter);
    return rabbitListenerContainerFactory;
  }

  @Bean
  public Jackson2JsonMessageConverter jackson2JsonMessageConverter(ObjectMapper xssObjectMapper) {
    return new Jackson2JsonMessageConverter(xssObjectMapper);
  }
}

然后在listener中直接加一个@RabbitListener注解,指定containerFactory和queue即可。(这里如果已经bind了,可以不指定bindings)

@RabbitListener(containerFactory = "xxLlistenerContainer",
      bindings = @QueueBinding(value = @Queue(value = "xxQueue"E, durable = "true"),
          exchange = @Exchange(value = “xxexchange”,  durable = "true"),
          key = "xxRoutingKey"))
  public void processInvoice(ProcessMessage processMessage)

2. 现在需要增加一个vhost的queue,一开始我以为不能继续使用这种默认注入的方式,就在spring boot的application中,增加了@SpringBootApplication(exclude = {RabbitAutoConfiguration.class})

@Slf4j
@EnableMbean
@EnableConfigCenter
@SpringBootApplication(exclude = {RabbitAutoConfiguration.class})
public class ApiApplication {
但是发现启动不成功,因为进入RabbitAutoConfiguration.java会发现他还会加载很多其他的东西,所以仍然需要使用。只需要更改:

(1)在RabbitMqConfig上加@EnableRabbit和@EnableConfigurationProperties(RabbitProperties.class)注解,EnableConfigurationProperties是为了引入配置rabbitProperties。

@Slf4j
@Configuration
@ComponentScan
@EnableRabbit
@EnableConfigurationProperties(RabbitProperties.class)
public class RabbitMqConfig {

  @Value("${spring.rabbitmq.virtual-host2}")
  private String virtualHost2;

  @Autowired
  private RabbitProperties rabbitProperties;

//【START】default mq config
  @Bean
  @Primary
  public ConnectionFactory connectionFactory() {
    return this.buildConnectionFactory(rabbitProperties.getHost(), rabbitProperties.getPort(),
        rabbitProperties.getUsername(), rabbitProperties.getPassword(), rabbitProperties.getVirtualHost());
  }

  @Bean
  @Primary
  public SimpleRabbitListenerContainerFactory listenerContainerFactory(
      @Qualifier("connectionFactory") ConnectionFactory connectionFactory,
      @Qualifier("jackson2JsonMessageConverter") Jackson2JsonMessageConverter jackson2JsonMessageConverter) {
    return this.buildSimpleRabbitListenerContainerFactory(connectionFactory, jackson2JsonMessageConverter);
  }

  @Bean
  @Primary
  public RabbitTemplate rabbitTemplate(
      @Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
    return new RabbitTemplate(connectionFactory);
  }

  @Bean
  @Primary
  public AmqpAdmin amqpAdmin(@Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
    return new RabbitAdmin(connectionFactory);
  }
  //【END】default mq config

  @Bean
  public ConnectionFactory featureConnectionFactory() {
    return this.buildConnectionFactory(rabbitProperties.getHost(), rabbitProperties.getPort(),
        rabbitProperties.getUsername(), rabbitProperties.getPassword(), featureVirtualHost);
  }

  @Bean
  public SimpleRabbitListenerContainerFactory featureListenerContainerFactory(
      @Qualifier("featureConnectionFactory") ConnectionFactory connectionFactory,
      @Qualifier("jackson2JsonMessageConverter") Jackson2JsonMessageConverter jackson2JsonMessageConverter) {
    return this.buildSimpleRabbitListenerContainerFactory(connectionFactory, jackson2JsonMessageConverter);
  }

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

  @Bean
  public AmqpAdmin featureAmqpAdmin(@Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
    return new RabbitAdmin(connectionFactory);
  }

  private ConnectionFactory buildConnectionFactory(String host, int port, String username, String password,
      String virtualHost) {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
    connectionFactory.setHost(host);
    connectionFactory.setPort(port);
    connectionFactory.setUsername(username);
    connectionFactory.setPassword(password);
    connectionFactory.setVirtualHost(virtualHost);
    return connectionFactory;
  }

  private SimpleRabbitListenerContainerFactory buildSimpleRabbitListenerContainerFactory(
      ConnectionFactory connectionFactory, Jackson2JsonMessageConverter jackson2JsonMessageConverter) {
    SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setMessageConverter(jackson2JsonMessageConverter);
    factory.setMaxConcurrentConsumers(5);
    return factory;
  }

只需要根据自定义rabbitProperties中的第二个vhost,另外定义featureConnectionFactory以及featureListenerContainerFactory。(2).  对于默认的default rabbit listener,containerfactory指定为listenerContainerFactory(可以自定义名称,比如featureListenerContainer2;不过如果去掉autoconfiguration,那么必须指定为这个名字,否则会抛异常),对于另外的listener,指定RabbitMqConfig中相应的containerFactory,这里是featureListenerContainerFactory。

你可能感兴趣的:(mq)