RabbitMQ-基础

什么是MQ?【熟悉】

  • 定义:MessageQueue消息队列

  • 组成:

    • 中间件:队列载体
    • 生产者
    • 消费者
  • 优势

    • 应用解耦:提供了程序的可扩展性
    • 异步提速:提高了系统的性能
    • 削峰填谷:提升了系统的稳定性
  • 劣势

    • 增加了系统维护成本
    • 系统可用性降低(忽略)
  • 场景的产品

    • Pulsar 最新流行

在这里插入图片描述

什么是Rabbitmq

  • 定义:是一个基于AMQP协议实现的一款消息中间件

  • 组成:

在这里插入图片描述

Rabbitmq API发送消息[精通]

  • 建立连接

    //1.创建连接工厂=====================
    ConnectionFactory factory = new ConnectionFactory();
    //2. 设置参数
    factory.setHost("172.16.98.133");//ip  默认值 localhost
    factory.setPort(5672); //端口  默认值 5672
    factory.setVirtualHost("/itcast");//虚拟机 默认值/
    factory.setUsername("heima");//用户名 默认 guest
    factory.setPassword("heima");//密码 默认值 guest
    //3. 创建连接 Connection
    Connection connection = factory.newConnection();
    //4. 创建Channel==============================
    Channel channel = connection.createChannel();
    
  • 业务处理:向一个队列中发送消息

    • 创建队列

      	/*
              queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
              参数:
                  1. queue:队列名称
                  2. durable:是否持久化,当mq重启之后,还在
                  3. exclusive:
                      * 是否独占。只能有一个消费者监听这队列
                      * 当Connection关闭时,是否删除队列
                      *
                  4. autoDelete:是否自动删除。当没有Consumer时,自动删除掉
                  5. arguments:参数。
      
               */
              //如果没有一个名字叫hello_world的队列,则会创建该队列,如果有则不会创建
              channel.queueDeclare("hello_world",true,false,false,null);
      
    • 创建交换机

      /*
      
             exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable, boolean autoDelete, boolean internal, Map<String, Object> arguments)
             参数:
              1. exchange:交换机名称
              2. type:交换机类型
                  DIRECT("direct"),:定向
                  FANOUT("fanout"),:扇形(广播),发送消息到每一个与之绑定队列。
                  TOPIC("topic"),通配符的方式
              3. durable:是否持久化
              4. autoDelete:自动删除,没有队列的
              5. internal:内部使用。 一般false
              6. arguments:参数
              */
      
             String exchangeName = "test_fanout";
              //5. 创建交换机
              channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT,true,false,false,null);
              
      
    • 绑定队列和交换机

      //6. 创建队列
              String queue1Name = "test_fanout_queue1";
              String queue2Name = "test_fanout_queue2";
              channel.queueDeclare(queue1Name,true,false,false,null);
              channel.queueDeclare(queue2Name,true,false,false,null);
              //7. 绑定队列和交换机
              /*
              queueBind(String queue, String exchange, String routingKey)
              参数:
                  1. queue:队列名称
                  2. exchange:交换机名称
                  3. routingKey:路由键,绑定规则
                      如果交换机的类型为fanout ,routingKey设置为""
               */
              channel.queueBind(queue1Name,exchangeName,"");
              channel.queueBind(queue2Name,exchangeName,"");
      
    • 发送消息

      	/*
              basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
              参数:
                  1. exchange:交换机名称。简单模式下交换机会使用默认的 ""
                  2. routingKey:路由名称
                  3. props:配置信息
                  4. body:发送消息数据
      
               */
      
              String body = "hello rabbitmq~~~";
      
              //6. 发送消息simple、work
              channel.basicPublish("","hello_world",null,body.getBytes());
      		//pub、sub模式
      		channel.basicPublish(exchangeName,"",null,body.getBytes());
      
  • 释放连接

    channel.close();
    connection.close();
    

Rabbitmq API监听消息[精通]

  • 建立连接

    //1.创建连接工厂=====================
    ConnectionFactory factory = new ConnectionFactory();
    //2. 设置参数
    factory.setHost("172.16.98.133");//ip  默认值 localhost
    factory.setPort(5672); //端口  默认值 5672
    factory.setVirtualHost("/itcast");//虚拟机 默认值/
    factory.setUsername("heima");//用户名 默认 guest
    factory.setPassword("heima");//密码 默认值 guest
    //3. 创建连接 Connection
    Connection connection = factory.newConnection();
    //4. 创建Channel==============================
    Channel channel = connection.createChannel();
    
  • 处理业务逻辑

    • 监听消息队列

      		/*
              basicConsume(String queue, boolean autoAck, Consumer callback)
              参数:
                  1. queue:队列名称
                  2. autoAck:是否自动确认
                  3. callback:回调对象
      
               */
              channel.basicConsume("hello_world",true,consumer);
      
    • 处理消息

      // 接收消息
              Consumer consumer = new DefaultConsumer(channel){
                  /*
                      回调方法,当收到消息后,会自动执行该方法
      
                      1. consumerTag:标识
                      2. envelope:获取一些信息,交换机,路由key...
                      3. properties:配置信息
                      4. body:数据
      
                   */
                  @Override
                  public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                      System.out.println("consumerTag:"+consumerTag);
                      System.out.println("Exchange:"+envelope.getExchange());
                      System.out.println("RoutingKey:"+envelope.getRoutingKey());
                      System.out.println("properties:"+properties);
                      System.out.println("body:"+new String(body));
                  }
              };
      
  • 释放连接

    • 消费端一般不主动关闭

Rabbitmq的5中使用方式【精通】

  • QUEUE存在多个消费者时,其消费者之间是轮询获取消息的方式
名称exchangeroutingkey消费者数量
simple默认交换机队列名称1
work默认交换机队列名称N
pub/sub自定义(fanout)“”N
routing自定义(driect)自定义全名称N
topic自定义(topic)支持通配符N
  • #:0或者多级的匹配
  • *:一级的匹配

Spring集成Rabbitmq生产端【熟悉】

  • 导包

    <dependency>
                <groupId>org.springframework.amqp</groupId>
                <artifactId>spring-rabbit</artifactId>
                <version>2.1.8.RELEASE</version>
            </dependency>
    
  • 配置

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:rabbit="http://www.springframework.org/schema/rabbit"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           https://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/rabbit
           http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
        <!--加载配置文件-->
        <context:property-placeholder location="classpath:rabbitmq.properties"/>
    
        <!-- 定义rabbitmq connectionFactory -->
        <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}"
                                   port="${rabbitmq.port}"
                                   username="${rabbitmq.username}"
                                   password="${rabbitmq.password}"
                                   virtual-host="${rabbitmq.virtual-host}"/>
        <!--定义管理交换机、队列-->
        <rabbit:admin connection-factory="connectionFactory"/>
    
        <!--定义持久化队列,不存在则自动创建;不绑定到交换机则绑定到默认交换机
        默认交换机类型为direct,名字为:"",路由键为队列的名称
        -->
        <!--
            id:bean的名称
            name:queue的名称
            auto-declare:自动创建
            auto-delete:自动删除。 最后一个消费者和该队列断开连接后,自动删除队列
            exclusive:是否独占
            durable:是否持久化
        -->
    
        <rabbit:queue id="spring_queue" name="spring_queue" auto-declare="true" />
    
        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~广播;所有队列都能收到消息~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <!--定义广播交换机中的持久化队列,不存在则自动创建-->
        <rabbit:queue id="spring_fanout_queue_1" name="spring_fanout_queue_1" auto-declare="true"/>
    
        <!--定义广播交换机中的持久化队列,不存在则自动创建-->
        <rabbit:queue id="spring_fanout_queue_2" name="spring_fanout_queue_2" auto-declare="true"/>
    
        <!--定义广播类型交换机;并绑定上述两个队列-->
        <rabbit:fanout-exchange id="spring_fanout_exchange" name="spring_fanout_exchange"  auto-declare="true">
            <rabbit:bindings>
                <rabbit:binding  queue="spring_fanout_queue_1"  />
                <rabbit:binding queue="spring_fanout_queue_2"/>
            </rabbit:bindings>
        </rabbit:fanout-exchange>
    
        <!--<rabbit:direct-exchange name="aa" >
            <rabbit:bindings>
                &lt;!&ndash;direct 类型的交换机绑定队列  key :路由key  queue:队列名称&ndash;&gt;
                <rabbit:binding queue="spring_queue" key="xxx"></rabbit:binding>
            </rabbit:bindings>
    
        </rabbit:direct-exchange>-->
    
        <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~通配符;*匹配一个单词,#匹配多个单词 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
        <!--定义广播交换机中的持久化队列,不存在则自动创建-->
        <rabbit:queue id="spring_topic_queue_star" name="spring_topic_queue_star"  auto-declare="true"/>
        <!--定义广播交换机中的持久化队列,不存在则自动创建-->
        <rabbit:queue id="spring_topic_queue_well" name="spring_topic_queue_well" auto-declare="true"/>
        <!--定义广播交换机中的持久化队列,不存在则自动创建-->
        <rabbit:queue id="spring_topic_queue_well2" name="spring_topic_queue_well2" auto-declare="true"/>
    
        <rabbit:topic-exchange id="spring_topic_exchange"  name="spring_topic_exchange" auto-declare="true">
            <rabbit:bindings>
                <rabbit:binding pattern="heima.*"  queue="spring_topic_queue_star"/>
                <rabbit:binding pattern="heima.#" queue="spring_topic_queue_well"/>
                <rabbit:binding pattern="itcast.#" queue="spring_topic_queue_well2"/>
            </rabbit:bindings>
        </rabbit:topic-exchange>
    
        <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
        <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
    </beans>
    
  • 编码

    	//1.注入 RabbitTemplate
        @Autowired
        private RabbitTemplate rabbitTemplate;
    
    
        @Test
        public void testHelloWorld(){
            //2.发送消息
    
            rabbitTemplate.convertAndSend("spring_queue","hello world spring....");
        }
    

Spring集成Rabbitmq消费端【熟悉】

  • 导包与生产端一致

  • 配置

    <bean id="springQueueListener" class="com.itheima.rabbitmq.listener.SpringQueueListener"/>
    <rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">
        <rabbit:listener ref="springQueueListener" queue-names="spring_queue"/>
    </rabbit:listener-container>
    
  • 编码

    • 需要实现MessageListener接口
    public class SpringQueueListener implements MessageListener {
        @Override
        public void onMessage(Message message) {
            //打印消息
            System.out.println(new String(message.getBody()));
        }
    }
    

SpringBoot集成Rabbitmq【精通】

  • 导包

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

    spring:
      rabbitmq:
        host: localhost # ip
        port: 5672
        username: guest
        password: guest
        virtual-host: /
    
  • 编码

    • 发送
    //1.注入RabbitTemplate
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @Test
    public void testSend(){
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"boot.haha","boot mq hello~~~");
    }
    
    • 监听
    @Component
    public class AckListener {
        @RabbitListener(queues = "TOPIC_QUEUE_SPRINGBOOT_1")
        public void onMessage(Message message,Channel channel) throws IOException {
            
        }
    }
    

SpringBoot中JavaConfig方式声明队列、交换信息【精通】

  • QueueBuilder:声明queue构建器
  • ExchangeBuilder:声明交换机构建器
  • BindingBuilder:声明绑定关系构建器
    //1.交换机
    @Bean
    public Exchange bootExchange(){
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
    }


    //2.Queue 队列
    @Bean
    public Queue bootQueue(){
        return QueueBuilder.durable(QUEUE_NAME).build();
    }

    //3. 队列和交互机绑定关系 Binding
    /*
        1. 知道哪个队列
        2. 知道哪个交换机
        3. routing key
     */
    @Bean
    public Binding bindQueueExchange(@Qualifier("bootQueue") Queue queue, @Qualifier("bootExchange") Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("boot.#").noargs();
    }

Queue 队列
@Bean
public Queue bootQueue(){
return QueueBuilder.durable(QUEUE_NAME).build();
}

//3. 队列和交互机绑定关系 Binding
/*
    1. 知道哪个队列
    2. 知道哪个交换机
    3. routing key
 */
@Bean
public Binding bindQueueExchange(@Qualifier("bootQueue") Queue queue, @Qualifier("bootExchange") Exchange exchange){
    return BindingBuilder.bind(queue).to(exchange).with("boot.#").noargs();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值