rabbitmq 消息模式

184 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

六 Rabbitmq五种发送消息的模式代码实现

www.rabbitmq.com/getstarted.…

1. 简单模式(hello world)

image-20200926112439109.png

步骤:

  1. 创建项目

    • web/lombok/rabbitmq
  2. 编写配置文件

    • #mq配置
      spring:
        rabbitmq:
          host: 192.168.200.132
      
  3. 创建队列----》Java Bean

    import org.springframework.amqp.core.Queue;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    ​
    @Configuration //声明是一个配置类
    public class QueueConfig {
        
        /**
         * @Author: guodong 
         * @Date: 11:33 2020/9/26
         * @Parms []
         * @ReturnType: org.springframework.amqp.core.Queue
         * @Description: 创建itheima-31队列
        */
        @Bean
        public Queue queue(){
            return new Queue("itheima-31");
        }
    ​
    }
    ​
    
  4. 创建生产者发送消息

    @RestController
    @RequestMapping("hello")
    @Slf4j
    public class HelloController {
    ​
        @Autowired
        private RabbitTemplate rabbitTemplate;
    ​
        @GetMapping("sendMsg/{msg}")
        public void sendMsg(@PathVariable String msg){
            /*
                第一个参数是routingkey: 路由键,默认是队列名称
                第二个参数是发送的消息
             */
            rabbitTemplate.convertAndSend("itheima-31", msg);
    ​
            log.info("发送消息完毕 : {}" , msg);
        }
    }
    ​
    
  5. 创建消费者监听消息

    @RabbitListener(queues = "itheima-31") //声明监听的消息队列
    @Slf4j
    @Component
    public class ConsumerListener {
    ​
        @RabbitHandler //转换消息
        public void receiveMsg(String msg){
            log.info("消费者接收到消息: {}" , msg);
        }
    ​
    }
    
2. 工作队列模式(work queue)

image-20200926114540520.png

步骤:

  1. 复制粘贴,需要修改日志输出,以便查看是那个消费者接收到消息

小结:

  • 工作队列模式特点:

    • 消费者之间是竞争关系
    • 消费者之间会进行轮训接收消息
    • 以上两种模式共有的特点是不需要声明交换机,但是使用的是默认的交换机。
3. 发布订阅模式
  • Fanout(广播类型交换机)

image-20200926120334983.png

**步骤:**

0.  创建fanout类型交换机
0.  创建fanout.A、fanout.B、fanout.C
0.  完成三个队列与交换机的绑定
0.  发送消息
0.  编写三个消费者

**代码实现:**

-   创建队列+交换机并且完成绑定

    ```
     /**
         * @Author: guodong 
         * @Date: 12:06 2020/9/26
         * @Parms []
         * @ReturnType: org.springframework.amqp.core.FanoutExchange
         * @Description: 创建fanout类型交换机
        */
        @Bean
        public FanoutExchange fanoutExchange(){
            return new FanoutExchange("itheihei");
        }
        /*
            bean在创建时默认的bean name是方法名
         */
        @Bean
        public Queue fanoutA(){
            return new Queue("fanout.A");
        }
        @Bean
        public Queue fanoutB(){
            return new Queue("fanout.B");
        }
        @Bean
        public Queue fanoutC(){
            return new Queue("fanout.C");
        }
    ​
        /*
            交换机与队列完成绑定
         */
        @Bean
        public Binding bindFanoutA(FanoutExchange fanoutExchange, Queue fanoutA){
            return BindingBuilder.bind(fanoutA).to(fanoutExchange);
        }
    ​
        @Bean
        public Binding bindFanoutB(FanoutExchange fanoutExchange, Queue fanoutB){
            return BindingBuilder.bind(fanoutB).to(fanoutExchange);
        }
        @Bean
        public Binding bindFanoutC(FanoutExchange fanoutExchange, Queue fanoutC){
            return BindingBuilder.bind(fanoutC).to(fanoutExchange);
        }
    ```

-   发送消息

    ```
     @GetMapping("sendMsgEx/{msg}")
        public void sendMsgEx(@PathVariable String msg){
            /*
                第一个参数是routingkey: 路由键,默认是队列名称
                第二个参数是发送的消息
             */
            rabbitTemplate.convertAndSend("itheihei", "", msg);
    ​
            log.info("发送广播类型消息完毕 : {}" , msg);
        }
    ```

-   接收消息

    ```
    @RabbitListener(queues = "fanout.A") //声明监听的消息队列
    @Slf4j
    @Component
    public class FanoutListenerA {
    ​
        @RabbitHandler //转换消息
        public void receiveMsg(String msg){
            log.info("fanoutA 接收到消息: {}" , msg);
        }
    }
    ```

**小结:**

-   广播类型消息特点:

    -   需要声明fanout类型交换机
    -   需要完成交换机与队列的绑定
    -   发送的消息可以被所有完成绑定的队列接收到,形成广播类型的消息
  • Direct(路由键模式/点对点模式)

image-20200926144901903.png

**步骤:**

-   创建交换机
-   创建队列
-   完成队列与交换机的绑定并且设置路由键

**小结:**

-   direct模式的特点:

    -   需要声明direct类型的交换机
    -   完成队列与交换机的绑定并且需要设置路由键
    -   在发送消息时需要指定路由键,只有符合规则(完全匹配)的路由键才可以将消息从交换机路由至队列,
    -   如上图所示如果routingKey为itheima则A和B全部可以接收到消息,如果routingKey为itcast则只有B队列可以接收到消息
  • Topic(主题模式/通配符模式)

image-20200926145326929.png

**步骤:**

-   创建交换机
-   创建队列
-   完成队列与交换机的绑定并且设置路由键

**小结:**

-   topic模式特点:

    -   需要声明direct类型的交换机

    -   完成队列与交换机的绑定并且需要设置路由键

    -   在发送消息时需要指定路由键,只有符合规则才会路由至队列

    -   规则:

        -   "*" : 不多不少正好匹配一个词
        -   "#": 匹配大于等于0个词
        -   究竟有多少个词是用 "."来判断的
        -   上图所示的案例中并且必须以itheima作为第一个词存在