Spring Boot 集成 RabbitMQ

821 阅读3分钟

RabbitMQ

RabbitMQ是实现了高级队列消息协议(AMQP: Advanced Message Queuing Protocol)的开源消息代理软件,它也被称作为面向消息的中间件。RabbitMQ服务器使用了Erlang语言编写而成,它具有高性能,可伸缩的特性。

1.安装

各个平台的安装请参考官网链接:RabbitMQ安装

2.基本概念

2.1 RabbitMQ角色定义

  • Producer:消息生产者。生产并发送消息。
  • Consumer:消息消费者。接受并处理消息。
  • Borker:消息队列服务器的实体。他负责接受生产者产生的消息,并将消息发送至接收者或者其它的Broker。
  • Exchange:消息交换机。消息被创建后第一个到达的地方,通过它指定的路由规则,将消息分发到不同的消息队列中去。
  • Routing Key:路由关键字。Exchange根据这个关键字进行消息的投递。
  • Queue:消息队列。消息被发送及路由之后到达的地方。到达Queue的消息即进入了等待消费的状态。每一个消息都可以被发送到一个或多个交换机。
  • Binding:绑定。连接Exchange和Queue,将它们按照路由规则绑定起来。
  • Virtual Host:虚拟主机。是对Broker的虚拟划分,将消费者,生产者及它们依赖的AMQP相关的结构进行隔离。
  • Connection:连接。生产者,消费者及Broker之间进行通信的物理网络。
  • Channel:消息通道。用于连接生产者和消费者。在每一个连接里,可以建立多个Channel,每一个Channel代表一次回话任务,使用Channel可以隔离同一个连接中的不同的交互内容。

2.2 Exchange类型

  • Direct交换机:完全根据消息的Routing Key进行消息投递。
  • Topic交换机:对Routing Key进行模式匹配后进行消息投递。使用#匹配一个或者多个词,使用*匹配正好一个词。
  • Fanout交换机:不需要任何Key,采用广播模式的方式将一个消息投递到与该交换机绑定的所有队列。

2.3 消息持久化

  • Exchange持久化:声明时指定durable等于1(1是持久化)。
  • Queue持久化:声明时指定durable等于1(1是持久化)。
  • 消息持久化:声明时指定delivery_mode等于2(1是非持久化)。

3.消息投递大致流程

  1. 客户端连接消息队列服务器并打开一个Channel。
  2. 客户端声明一个Exchange并设置相关属性。
  3. 客户端声明一个Queue并设置相关属性。
  4. 客户端使用Routing Key在Exchange和Queue之间建立绑定关系。
  5. 客户端投递消息到Exchange。
  6. Exchange根据根据消息的Key和已经设置的Binding进行消息路由,将消息投递到一个或多个Queue里。

4.Spring Boot应用整合RabbitMQ

4.1 准备

安装并开启RabbitMQ服务

4.2 构建SpringBoot应用

  1. 新建一个Spring Boot工程

  2. 添加依赖:spring-boot-starter-amqp

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>
    
  3. 配置RabbitMQ

    spring:
      rabbitmq:
        host: 127.0.0.1
        port: 5672
        userName: admin
        password: admin
        virtual-host: /
    
  4. RabbitMQ配置类

    @Configuration
    public class RabbitConfig {
    
        /**
         * 声明交换机
         * String: 交换机名称
         * Boolean: 是否持久化
         * Boolean: 是否自动删除
         */
        /** Direct Exchange **/
        @Bean
        public DirectExchange directExchange() {
            return new DirectExchange("DIRECT_EXCHANGE", true, false);
        }
        /** Topic Exchange **/
        @Bean
        public TopicExchange topicExchange() {
            return new TopicExchange("TOPIC_EXCHANGE", true, false);
        }
        /** Fanout Exchange **/
        @Bean
        public FanoutExchange fanoutExchange() {
            return new FanoutExchange("FANOUT_EXCHANGE", true, false);
        }
    
        /**
         * 声明消息队列
         * String: 消息队列名称
         * Boolean: 是否持久化
         */
        @Bean
        public Queue helloQueue() {
            return new Queue("HELLO_QUEUE", true);
        }
        @Bean
        public Binding helloBinding() {
            return BindingBuilder.bind(helloQueue()).to(directExchange()).with("mq.hello");
        }
    }
    
  5. RabbitMQ生产者

    @Component
    public class producer {
    
        @Autowired
        private AmqpTemplate rabbitTemplate;
    
        public void send() {
            rabbitTemplate.convertAndSend("HELLO_QUEUE", "hello mq!");
        }
    }
    
  6. RabbitMQ消费者

    @Component
    @RabbitListener(queues = "HELLO_QUEUE")
    public class consumer {
    
        @RabbitHandler
        public void process(String message) {
            System.out.println(message);
        }
    }