Spring Boot 配置两个Rabbit Mq

 1.背景

一个spring boot项目配置一个rabbit mq很常见,如何配置两个以及两个以上的mq?本篇文章将结合代码说明如何配置两个rabbit mq(talk is cheap, show me the code)。

2.项目结构

 
  1. <groupId>cn.honorzhang</groupId>
  2. <artifactId>my-springboot-rabbitmq</artifactId>
  3. <version>1.0.0</version>
  4. <modules>
  5. <module>my-springboot-rabbitmq-amqp</module>
  6. <module>my-springboot-rabbitmq-model</module>
  7. </modules>
  8. <packaging>pom</packaging>
  9. <parent>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-parent</artifactId>
  12. <version>2.2.7.RELEASE</version></parent>
 

如上代码所示,本项目包含两个模型,一个model模型,主要定义mq传递消息所用的模型,解析mq消息并转换成自己设计的模型。amqp模型主要是两个mq的配置,mq的公共配置,以及收发消息的逻辑代码。本例中定义了两个mq,分别包含消息的生产,消息的接收。

3.代码的讲解

3.1 mq的配置

 
  1. spring.rabbitmq.first.host=${spring.rabbitmq.first.host}
  2. spring.rabbitmq.first.port=${spring.rabbitmq.first.port}
  3. spring.rabbitmq.first.user=${spring.rabbitmq.first.user}
  4. spring.rabbitmq.first.password=${spring.rabbitmq.first.password}
  5. spring.rabbitmq.first.virtual-host=${spring.rabbitmq.first.virtual-host}
  6. spring.rabbitmq.first.exchange=${spring.rabbitmq.first.exchange}
  7. spring.rabbitmq.first.routing.key=${spring.rabbitmq.first.routing.key}
 

其中queue的名称配置为环境变量,在消费端@RabbitListener中直接读取此环境变量的值。

3.2 配置代码

 
  1. @Configuration
  2. @PropertySource(value = "classpath:first-mq-config.properties")
  3. public class FirstMqConfig {
  4.  
  5. @Bean(name = "firstConnectionFactory")
  6. @Primary
  7. public ConnectionFactory firstConnectionFactory(
  8. @Value("${spring.rabbitmq.first.host}") String host,
  9. @Value("${spring.rabbitmq.first.port}") String port,
  10. @Value("${spring.rabbitmq.first.user}") String username,
  11. @Value("${spring.rabbitmq.first.password}") String password,
  12. @Value("${spring.rabbitmq.first.virtual-host}") String virtualHost){
  13.  
  14. return constructConnectionFactory(host, port, username, password, virtualHost);
  15. }
  16.  
  17. @Bean(name = "firstRabbitTemplate")
  18. public RabbitTemplate firstRabbitTemplate(
  19. @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory
  20. ) {
  21. RabbitTemplate firstRabbitTemplate = new RabbitTemplate(connectionFactory);
  22. return firstRabbitTemplate;
  23. }
  24.  
  25.  
  26. // 配置监听1
  27. @Bean(name = "firstFactory")
  28. public SimpleRabbitListenerContainerFactory firstFactory(
  29. SimpleRabbitListenerContainerFactoryConfigurer configurer,
  30. @Qualifier("firstConnectionFactory") ConnectionFactory connectionFactory
  31. ) {
  32. SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
  33. configurer.configure(factory, connectionFactory);
  34. return factory;
  35. }
  36.  
  37.  
  38.  
  39.  
  40. private ConnectionFactory constructConnectionFactory(
  41. String host, String port, String username, String password, String virtualHost){
  42. CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
  43. connectionFactory.setHost(host);
  44. connectionFactory.setPort(Integer.parseInt(port));
  45. connectionFactory.setUsername(username);
  46. connectionFactory.setPassword(password);
  47. connectionFactory.setVirtualHost(virtualHost);
  48.  
  49. return connectionFactory;
  50. }
  51.  
  52. }
 

还有mq的一般配置,对于发送消息的序列化配置,以及接收消息的模型转换配置

 
  1. @Configuration
  2. public class MqCommonConfig {
  3. @Bean
  4. public MessageConverter jackson2JsonMessageConverter(){
  5. return new Jackson2JsonMessageConverter();
  6. }
  7.  
  8. /**
  9. * 解决方法:添加这个类进行序列化解析
  10. * 会自动识别
  11. * @param objectMapper json序列化实现类
  12. * @return mq 消息序列化工具
  13. */
  14. @Bean
  15. public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) {
  16. return new Jackson2JsonMessageConverter(objectMapper);
  17. }
  18. }
 

3.3 消费端与生产代码配置

生产端代码

 
  1. @Resource(name = "firstRabbitTemplate")
  2. private RabbitTemplate firstRabbitTemplate;
  3.  
  4.  
  5. @Value("${spring.rabbitmq.first.exchange:@null}")
  6. private String firstExchange;
  7.  
  8. @Value("${spring.rabbitmq.first.routing.key:@null}")
  9. private String firstRoutingKeyRoute;
  10.  
  11.  
  12. public void sendMessageByFirstMq() {
  13. RabbitMqMsg rabbitMqMsg = constructMqMsg("first", "**********first**********");
  14. log.info("-------------------send first rabbit mq info-----------------");
  15. firstRabbitTemplate.convertAndSend(
  16. firstExchange, firstRoutingKeyRoute, rabbitMqMsg, generateMqHeader());
  17.  
  18. }
  19.  
  20.  
  21. private RabbitMqMsg constructMqMsg(String id, String text) {
  22.  
  23. return RabbitMqMsg.builder()
  24. .msgId(id)
  25. .msgText(text)
  26. .build();
  27.  
  28. }
  29.  
  30.  
  31. private MessagePostProcessor generateMqHeader() {
  32. return message -> {
  33. MessageProperties properties = message.getMessageProperties();
  34. properties.setHeader("content-type", "application/json");
  35. properties.setHeader("content-encoding", "UTF-8");
  36. return message;
  37. };
  38. }
 

消费端代码

 
  1. @RabbitListener(queues = "${spring.rabbitmq.first.queue.name}", containerFactory="firstFactory")
  2. public void processFirstMqMessage(@Payload RabbitMqMsg message) {
  3. log.info("**********processMessage first message****************: {}", message);
  4. }
 

4.运行结果

第三部分的代码只展示了配置一个mq,配置多个mq是依葫芦画瓢,自行配置即可,本例中作者配置了两个mq,分别发送消息与接收消息,最后结果如下图所示。

5.代码地址

本篇博客的完整代码地址为github

6.最后的话

本篇博客给出了spring boot配置多个mq的实例,代码在实际应用中跑通,欢迎一起交流。

posted @ 2024-06-26 15:28  CharyGao  阅读(31)  评论(0编辑  收藏  举报