RabbitMQ快速使用详细

什么是MQ?【熟悉】

  • 定义:MessageQueue,消息队列

  • 应用场景:

  • 在微服务之间进行消息通信

  • 优势:

    • 应用解耦:提高系统的容错性和可扩展性
    • 异步提速:提高系统的吞吐量
    • 削峰填谷:提高系统的高可用
  • 劣势:

    • 系统复杂度提高
  • 相关产品

在这里插入图片描述

什么是RabbitMQ?【精通】

  • 定义:是一个实现了AMQP协议的消息中间件产品(AMQP是一个类似于http,用于网络传输数据格式组织的协议)
  • 组成:
    • producer(生产者):发送消息
      • channel(管道):用于同时读写消息,提升与broker通信效率的
    • consumer(消费者):接收消息
      • channel(管道):用于同时读写消息,提升与broker通信效率的
    • broker(一台Rabbitmq的服务器):存储和路由消息
      • VirtualHost:虚拟主机,作用类似mysql的database,用于隔离不同虚拟主机下的消息互相不影响
        • exchage:交互机,分发消息到队列
        • queue:队列,用于存储消息
      • Binding动作:把exchage与queue绑定在一起的过程
        • routingkey:消息的分发过滤条件

在这里插入图片描述

什么是JMS?

  • 定义:jms一套java提供的用于消息发送和接收的API接口

Docker安装rabbitmq

docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3-management

使用原生API来发送消息的步骤【精通】

  • 建立连接 —可以定义一个connection工具类

    • 创建连接工厂ConnectionFactory

      • VirtualHost
      • username
      • password
      • host
      • port
      ConnectionFactory factory = new ConnectionFactory();
      //2. 设置参数
      factory.setHost("172.16.98.133");//ip  默认值 localhost
      factory.setPort(5672); //端口  默认值 5672
      factory.setVirtualHost("/");//虚拟机 默认值/
      factory.setUsername("roc");//用户名 默认 guest
      factory.setPassword("roc");//密码 默认值 guest
      
    • 获取Channel

      //3. 创建连接 Connection
      Connection connection = factory.newConnection();
      //4. 创建Channel
      Channel channel = connection.createChannel();
      
  • 消息发送

    • 发送消息
    	/*
            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());
    		//8. 发送消息fanout
            channel.basicPublish(exchangeName,"",null,body.getBytes());
    
  • 资源释放

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

使用原生API来接收消息的步骤【精通】

  • 建立连接(参考发送)
  • 消息接收
/*
        basicConsume(String queue, boolean autoAck, Consumer callback)
        参数:
            1. queue:队列名称
            2. autoAck:是否自动确认
            3. callback:当时收到消息后,怎么处理消息

         */
        // 接收消息
        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));
            }
        };
        channel.basicConsume("hello_world",true,consumer);

API创建队列或交换机

  • 创建队列
/*
        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"),通配符的方式
            HEADERS("headers");参数匹配

        3. durable:是否持久化
        4. autoDelete:自动删除:没有一个队列与其绑定时,自动删除
        5. internal:内部使用。 一般false
        6. arguments:参数
        */

       String exchangeName = "test_fanout";
        //5. 创建交换机
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.FANOUT,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,"");

Rabbitmq的5中工作模式【精通】

  • 一个队列可以有多个消费者,但是一条消息同时只能被一个消费者处理。默认队列路由给消费者的策略是轮询。
  • 通配符
    • *:单级匹配
    • ##:多级匹配,类似之前学习的/**
  • 交换机与队列的关系:是多对多关系
    • 一个交换机可以绑定多个队列
    • 一个队列可以绑定到多个交换机
    • 一个队列可多次绑定到同个交换机
名称交换机消费者数量路由key
simple模式默认交换机1个队列名称
work模式默认交换机多个队列名称
订阅模式广播模式,fanout自定义fanout多个
订阅模式路由模式,routing自定义direct多个自定义key
订阅模式主题模式,topic自定义topic多个自定义key,可以使用通配符

在这里插入图片描述

Spring整合Ribbtmq【熟悉】

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

    • 初始化RabbitTemplate
    <!--加载配置文件-->
    <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}"/>
    <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
    <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
    
    • 创建队列和交换机[可选]
    <!--定义管理交换机、队列-->
    <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="roc.*"  queue="spring_topic_queue_star"/>
                <rabbit:binding pattern="roc.#" queue="spring_topic_queue_well"/>
                <rabbit:binding pattern="ou.#" queue="spring_topic_queue_well2"/>
            </rabbit:bindings>
        </rabbit:topic-exchange>
    
  • 编码

    • 接收消息
    <bean id="springQueueListener" class="com.roc.rabbitmq.listener.SpringQueueListener"/>
    
    <rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">
        <rabbit:listener ref="springQueueListener" queue-names="spring_queue"/>
    </rabbit:listener-container>
    
    import org.springframework.amqp.core.Message;
    import org.springframework.amqp.core.MessageListener;
    
    public class SpringQueueListener implements MessageListener {
        @Override
        public void onMessage(Message message) {
            //打印消息
            System.out.println(new String(message.getBody()));
        }
    }
    
    • 发送消息
	@Autowired
    private RabbitTemplate rabbitTemplate;

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

SpringBoot整合Rabbitmq【精通】

  • 导包
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • 配置
# 配置RabbitMQ的基本信息  ip 端口 username  password..
spring:
  rabbitmq:
    host: 172.16.98.133 # ip
    port: 5672
    username: guest
    password: guest
    virtual-host: /
  • 编码

    • 接收消息
    @Component
    public class RabbimtMQListener {
    
        @RabbitListener(queues = "boot_queue")
        public void ListenerQueue(Message message, Channel channel){
            //System.out.println(message);
            System.out.println(new String(message.getBody()));
        }
    
    }
    
    • 发送消息
	//1.注入RabbitTemplate
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Test
    public void testSend(){
        rabbitTemplate.convertAndSend("boot_topic_exchange","boot.haha","boot mq hello~~~");
    }

SpringBoot使用JavaConfig来创建交换机和队列【精通】

  • ExchangeBuilder:创建交换机
  • QueueBuilder:创建队列
  • BindingBuilder:创建绑定关系
//1.交换机
@Bean("bootExchange")
public Exchange bootExchange(){
    return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
}

//2.Queue 队列
@Bean("bootQueue")
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();
}


urable(true).build();
}

//2.Queue 队列
@Bean("bootQueue")
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();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值