多个springboot整合使用rabbitmq(使用注解的方式)

一、简述

先参考单个springboot使用rabbitmq和了解rabbitmq的五种模式

单个springboot整合rabbitmq_java-zh的博客-CSDN博客

二、创建项目

1、先创建两个springboot项目,一个做生产者,一个做消费者

 2、导包(生产者和消费者对应的内容都是一样)



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.4.1
        
    
    com.mq
    mqcloud
    0.0.1-SNAPSHOT
    
        2021.1
        1.8
        2.5.3
        1.18.14
        3.3.2
        1.2.75
        3.0.2
    

    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        
            org.springframework.boot
            spring-boot-devtools
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
        
            org.springframework.boot
            spring-boot-starter-aop
        
        
        
            org.springframework.cloud
            spring-cloud-starter-bootstrap
            ${spring-cloud-starter-bootstrap.version}
        
        
            com.alibaba
            fastjson
            ${alibaba.json.version}
        
        
            org.projectlombok
            lombok
            ${lombok.version}
            true
        
        
        
            io.jsonwebtoken
            jjwt
            0.9.0
        
        
            com.google.guava
            guava
            31.1-jre
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
            ${spring-cloud-alibaba.version}
        
        
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            ${spring-cloud-alibaba.version}
        


        
            org.apache.commons
            commons-lang3
            3.12.0
        
        
        
            com.common
            base
            1.0-SNAPSHOT
        

        
        
            org.springframework.boot
            spring-boot-starter-amqp
            3.0.4
        
    
    




3、编写配置文件

这里的配置文件生产者和消费者都一样

spring:
 rabbitmq:
    #如果是集群,用,隔开
    connection-timeout: 15000
    username: admin
    password: 123456
    #虚拟host,可以不设置
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: auto  #manual:手动处理 auto:自动处理
        #消费端监听个数(即@RabbitListenter开启几个线程去处理)
        concurrency: 10
        #消费端监听的最大个数
        max-concurrency: 10
        prefetch: 5
        default-requeue-rejected: true  #消费不成功的消息,拒绝入队
        retry:
          enabled: true #开启消息重试
          max-attempts: 4 #重试次数
          max-interval: 10000 #重试最大间隔时间
          initial-interval: 2000 #重试初始间隔时间
    #消息确认方式,通过correlated来确认
    publisher-confirm-type: correlated
    publisher-returns: true
    host: 192.168.139.128
    port: 5672
rabbitmq:
  #订阅模式(扇形模式)  
  fanout:
    exchange:
      #交换机名称
      name1: exchange.fanout
    queue:
      #通道名称
      name1: exchange.fanout.queue_1
      name2: exchange.fanout.queue_2
  #交换机模式  
  direct:
    exchange:
      name1: exchange.direct
    queue:
      name1: exchange.direct.queue_1
      name2: exchange.direct.queue_2
    routing:
      name1: exchange.direct.routing.1
      name2: exchange.direct.routing.2
  #主题模式  
  topic:
    exchange: 
      name1: exchange.topic
    queue:
      name1: exchange.topic.queue_1
      name2: exchange.topic.queue_2
    routing:
      name1: '#.routingkey.#'
      name2: routingkey.*      
                     

三、编码代码和测试结果

这里以rabbitmq的订阅模式(扇形模式)、路由器模式、主题模式为案例

3.1 扇形模式

生产者

@Autowired
private  RabbitTemplate rabbitTemplate;

// 订阅模式的交换机名称
@Value("${rabbitmq.fanout.exchange.name1}")
 private String exchangeName;


/**
  * 订阅模式(扇形模式)生产者
  *
  * @param context
  */
@GetMapping("/fanout/{context}")
public void sendMessage(@PathVariable String context) {
   System.out.println("需要发送得内容为:" + context);
   rabbitTemplate.convertAndSend(exchangeName, "", context);
}

消费者

注意:消费者绑定交换机和通道的值必须是固定常量值,所以我们直接从配置文件中读取

@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),
            value = @Queue(value = "${rabbitmq.fanout.queue.name1}")))
    @RabbitHandler
    public void consumerFanoutExchange(String context) {
        System.out.println("订阅模式,通道一接收到的内容为内容:" + context);
    }

@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),
            value = @Queue(value = "${rabbitmq.fanout.queue.name2}")))
    @RabbitHandler
    public void consumerFanoutExchange2(String context) {
        System.out.println("订阅模式,通道二接收到的内容为内容:" + context);
}

3.2 路由器模式

生产者

@Autowired
private  RabbitTemplate rabbitTemplate;

// 路由器模式的交换机名称
@Value("${rabbitmq.direct.exchange.name1}")
private String directName;

// 路由器模式的路由key1
@Value("${rabbitmq.direct.routing.name1}")
private String directRoutingKeyName1;

//路由器模式的路由key2
@Value("${rabbitmq.direct.routing.name2}")
private String directRoutingKeyName2;

/**
  * 路由器模式
  * @param context
  * @param routingkey
  */
@GetMapping("/direct")
public void sendMessageDirect(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {
   if (1 == routingkey) {
      rabbitTemplate.convertAndSend(directName, directRoutingKeyName1, context);
   } else if (2 == routingkey) {
      rabbitTemplate.convertAndSend(directName, directRoutingKeyName2, context);
   } else {
      System.out.println("数据非法");
   }
}

消费者


    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),
            value = @Queue(value = "${rabbitmq.direct.queue.name1}"),
            key = "${rabbitmq.direct.routing.name1}"))
    public void exchangeDirectRoutingKey1(String context, Message message) {
        System.out.println("key1:" + message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("路由器模式1 接收到的消息为:" + context);
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),
            value = @Queue(value = "${rabbitmq.direct.queue.name2}"),
            key = "${rabbitmq.direct.routing.name2}"))
    public void exchangeDirectRoutingKey2(String context, Message message) {
        System.out.println("key2:" + message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("路由器模式2 接收到的消息为" + context);
    }

3.3 主题模式

生产者

// 主题模式的交换机名称
    @Value("${rabbitmq.topic.exchange.name1}")
    private String topicName;

    //用来匹配主题模式对应的key
    public static final String EXCHANGE_TOPIC_CASE_KEY_1 = "topic.routingkey.case1";

    //如果case_key_2这样写,那么绑定case_key_1的队列一样会接收到,因为case_key_2也一样和key1匹配上
    public static final String EXCHANGE_TOPIC_CASE_KEY_2 = "routingkey.case2";

    @GetMapping("/topic")
    public void sendMessageTopic(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {
        if (1 == routingkey) {
            rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_1, context + routingkey);
        } else if (2 == routingkey) {
            rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_2, context + routingkey);
        } else {
            System.out.println("数据非法");
        }
    }

消费者

@RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1",  type = ExchangeTypes.TOPIC),
            value = @Queue(value = "${rabbitmq.topic.queue.name1}"),
            key = "${rabbitmq.topic.routing.name1}"))
    @RabbitHandler
    public void exchangeTopicRoutingKey1(String context, Message message) {
        System.out.println("key1:"+message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("主题模式1:接收的内容为:"+ context);
    }

@RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1", type = ExchangeTypes.TOPIC),
            value = @Queue(value = "${rabbitmq.topic.queue.name2}"),
            key = "${rabbitmq.topic.routing.name2}"))
    @RabbitHandler
    public void exchangeTopicRoutingKey2(String context,  Message message) {
        System.out.println("key2:"+message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("主题模式2:接收的内容为:"+ context);
    }

3.4 全量代码

生产者

@RestController
@RequiredArgsConstructor
@RequestMapping("/test/mq")
public class ProductController {

    private final RabbitTemplate rabbitTemplate;

    // 订阅模式的交换机名称
    @Value("${rabbitmq.fanout.exchange.name1}")
    private String exchangeName;

    // 路由器模式的交换机名称
    @Value("${rabbitmq.direct.exchange.name1}")
    private String directName;

    // 路由器模式的路由key1
    @Value("${rabbitmq.direct.routing.name1}")
    private String directRoutingKeyName1;

    //路由器模式的路由key2
    @Value("${rabbitmq.direct.routing.name2}")
    private String directRoutingKeyName2;

    // 主题模式的交换机名称
    @Value("${rabbitmq.topic.exchange.name1}")
    private String topicName;

    //用来匹配主题模式对应的key
    public static final String EXCHANGE_TOPIC_CASE_KEY_1 = "topic.routingkey.case1";

    //如果case_key_2这样写,那么绑定case_key_1的队列一样会接收到,因为case_key_2也一样和key1匹配上
    public static final String EXCHANGE_TOPIC_CASE_KEY_2 = "routingkey.case2";


    /**
     * 订阅模式(扇形模式)生产者
     *
     * @param context
     */
    @GetMapping("/fanout/{context}")
    public void sendMessage(@PathVariable String context) {
        System.out.println("需要发送得内容为:" + context);
        rabbitTemplate.convertAndSend(exchangeName, "", context);
    }

    /**
     * 路由器模式
     * @param context
     * @param routingkey
     */
    @GetMapping("/direct")
    public void sendMessageDirect(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {
        if (1 == routingkey) {
            rabbitTemplate.convertAndSend(directName, directRoutingKeyName1, context);
        } else if (2 == routingkey) {
            rabbitTemplate.convertAndSend(directName, directRoutingKeyName2, context);
        } else {
            System.out.println("数据非法");
        }
    }

    @GetMapping("/topic")
    public void sendMessageTopic(@RequestParam("context") String context, @RequestParam("routingkey") Integer routingkey) {
        if (1 == routingkey) {
            rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_1, context + routingkey);
        } else if (2 == routingkey) {
            rabbitTemplate.convertAndSend(topicName, EXCHANGE_TOPIC_CASE_KEY_2, context + routingkey);
        } else {
            System.out.println("数据非法");
        }
    }
}

消费者

@Component
public class ConsumerTest {


    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),
            value = @Queue(value = "${rabbitmq.fanout.queue.name1}")))
    @RabbitHandler
    public void consumerFanoutExchange(String context) {
        System.out.println("订阅模式,通道一接收到的内容为内容:" + context);
    }

    @RabbitListener(bindings = @QueueBinding(exchange = @Exchange(value = "${rabbitmq.fanout.exchange.name1}", type = ExchangeTypes.FANOUT),
            value = @Queue(value = "${rabbitmq.fanout.queue.name2}")))
    @RabbitHandler
    public void consumerFanoutExchange2(String context) {
        System.out.println("订阅模式,通道二接收到的内容为内容:" + context);
    }


    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),
            value = @Queue(value = "${rabbitmq.direct.queue.name1}"),
            key = "${rabbitmq.direct.routing.name1}"))
    public void exchangeDirectRoutingKey1(String context, Message message) {
        System.out.println("key1:" + message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("路由器模式1 接收到的消息为:" + context);
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.direct.exchange.name1}", type = ExchangeTypes.DIRECT),
            value = @Queue(value = "${rabbitmq.direct.queue.name2}"),
            key = "${rabbitmq.direct.routing.name2}"))
    public void exchangeDirectRoutingKey2(String context, Message message) {
        System.out.println("key2:" + message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("路由器模式2 接收到的消息为" + context);
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1",  type = ExchangeTypes.TOPIC),
            value = @Queue(value = "${rabbitmq.topic.queue.name1}"),
            key = "${rabbitmq.topic.routing.name1}"))
    @RabbitHandler
    public void exchangeTopicRoutingKey1(String context, Message message) {
        System.out.println("key1:"+message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("主题模式1:接收的内容为:"+ context);
    }

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange(value = "${rabbitmq.topic.exchange.name1", type = ExchangeTypes.TOPIC),
            value = @Queue(value = "${rabbitmq.topic.queue.name2}"),
            key = "${rabbitmq.topic.routing.name2}"))
    @RabbitHandler
    public void exchangeTopicRoutingKey2(String context,  Message message) {
        System.out.println("key2:"+message.getMessageProperties().getReceivedRoutingKey());
        System.out.println("主题模式2:接收的内容为:"+ context);
    }


}

你可能感兴趣的:(java-rabbitmq,spring,boot,rabbitmq)