RabbitMQ学习笔记

请添加图片描述

一、MQ的基本概念

  1. MQ概述
  • MQ,消息队列,存储消息的中间件。
  • 分布式系统通信的两种方式:直接远程调用 和 借助第三方 完成间接通信。
  • 发送方称为生产者,接收方称为消费者。
  1. MQ的优势和劣势

优势:

1. 应用解耦
系统的耦合性越高,容错性越低,可维护性就越低。
2. 异步提速
提升用户体验和系统吞吐量。
3. 削峰填谷
提高系统的稳定性。

劣势:

二、RabbitMQ安装

基本指令

启动
service rabbitmq-server start
停止
service rabbitmq-server stop
重启
service rabbitmq-server restart

开启web界面管理工具
rabbitmq-plugins enable rabbitmq_management

用户基本指令

  1. 查看用户
    rabbitmqctl list_users

  2. 新增用户
    rabbitmqctl add_user Username Password
    例如:
    rabbitmqctl add_user root root

  3. 设置权限
    rabbitmqctl set_user_tags root administrator

三、web界面管理工具

1.添加一个用户:
请添加图片描述
用户角色
1、超级管理员(administrator)
可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。
2、监控者(monitoring)
可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
3、策略制定者(policymaker)
可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。
4、普通管理者(management)
仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。
5、其他
无法登陆管理控制台,通常就是普通的生产者和消费者。

请添加图片描述

2.创建Virtual Hosts
请添加图片描述
3.设置权限
选择一个user。
请添加图片描述
在user界面可以看到,已添加权限。
请添加图片描述

四、RabbitMQ的五种模式

请添加图片描述

1. 简单模式

请添加图片描述

步骤:
1.创建工程(生产者和消费者)
2.分别添加依赖
3.编写生产生者发生消息
4.编写消费者接收消息

添加依赖

    <dependencies>
        <dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.13.0</version>
        </dependency>
    </dependencies>

生产者代码

public class Producer_HelloWorld {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置参数
        factory.setHost("120.79.155.127"); //默认值localhost
        factory.setVirtualHost("sparks");   //设置虚拟机
        factory.setUsername("root");      //设置用户名(默认guest)
        factory.setPassword("****");      //设置密码
        //3.创建连接 Connection
        Connection connection = factory.newConnection();
        //4.Channel
        Channel channel = connection.createChannel();
        //5.创建队列
        channel.queueDeclare("hello_world",true,false,false,null);
        //6.发送消息
        String body = "hello rabbitMQ";
        channel.basicPublish("","hello_world",null,body.getBytes());
        //释放资源
        channel.close();
        connection.close();

消费者代码

public class Consumer_Hello {
    public static void main(String[] args) throws IOException, TimeoutException {
        //1.创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //2.设置参数
        factory.setHost("120.79.155.127"); //默认值localhost
        factory.setVirtualHost("/sparks");   //设置虚拟机
        factory.setUsername("root");      //设置用户名(默认guest)
        factory.setPassword("root");      //设置密码
        //3.创建连接 Connection
        Connection connection = factory.newConnection();
        //4.Channel
        Channel channel = connection.createChannel();
        //5.创建队列
        channel.queueDeclare("hello_world",true,false,false,null);
                Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("consumerTag:" + consumerTag);
                System.out.println("envelope:" + envelope);
                System.out.println("properties:" + properties);
                System.out.println("body:" + body);
            }
        };
        channel.basicConsume("hello_world",true,consumer);

消费者不需要关闭资源

2. 工作队列模式

请添加图片描述
相当于一个生产者将消息发送给多个消费者,多个消费者轮流从队列接收处理消息。
只需要创建两个消费者,分别对该队列接收数据。

3.发布订阅模式

请添加图片描述
生产者发送消息不再直接发送给队列,而是发送给交换机。
Exchange: 交换机。
一方面,接收生产者发送的消息,另一方面,指定如何处理消息。
Exchange有以下三种类型:

  1. Fanout : 广播,将消息交给所有绑定到交换机的队列。
  2. Direct: 定向,把消息交给符合指定 routing key 的队列。
  3. Topic: 通配符,把消息交给符合 routing pattern (路由模式) 的队列。

发布订阅模式用的是Fanout类型。
生产者代码:

		//5.创建交换机
        String exchangeName = "test_fanout";
        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.绑定队列和交换机
        channel.queueBind(queue1Name,exchangeName,"");
        channel.queueBind(queue2Name,exchangeName,"");
        // 参数: 1. 队列名称 2. 交换机名称  3. routingKey 路由键,绑定规则  fanout 为 "";
        //8.发送消息
        String body = "发布订阅模式开启";
        channel.basicPublish(exchangeName,"",null,body.getBytes());

消费者只需要修改接收的队列名称即可。

4. Routing路由模式

请添加图片描述
Exchange 交换机类型: Direct

  • 队列与交换机绑定时,要指定一个RoutingKey(路由key)。
  • 消息的发送方在 向 Exchange 发送消息时,也必须指定消息的RoutingKey。
  • Exchange 根据消息的 RoutingKey 进行判断,只有队列的 RoutingKey 与消息的 RoutingKey 完全一致,才会接收消息。

生产者代码:

		//创建交换机
        String exchangeName = "test_direct";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.DIRECT,true,false,false,null);
        //6.创建队列
        //  String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
        String queue1Name = "test_direct_queue1";
        String queue2Name = "test_direct_queue2";
        channel.queueDeclare(queue1Name,true,false,false,null);
        channel.queueDeclare(queue2Name,true,false,false,null);
        //7.绑定队列和交换机
        channel.queueBind(queue1Name,exchangeName,"error");
        channel.queueBind(queue2Name,exchangeName,"info");
        channel.queueBind(queue2Name,exchangeName,"error");
        channel.queueBind(queue2Name,exchangeName,"warning");
        // 参数: 1. 队列名称 2. 交换机名称  3. routingKey 路由键,绑定规则  fanout 为 "";
        //8.发送消息
        String body = "日志信息,Routing模式开启";
        String error = "日志信息,Routing模式开启种出现错误";
        channel.basicPublish(exchangeName,"info",null,body.getBytes());
        channel.basicPublish(exchangeName,"error",null,error.getBytes());

消费者只需要修改接收消息的队列名称。

5. Topic通配符模式

请添加图片描述

  • *(星号) 可以完全代替一个词。

  • #(散列) 可以代替零或多个单词。
    Exchange 交换机模式: Topic

  • 队列与交换机绑定时,要指定一个通配符。

  • 消息的发送方在 向 Exchange 发送消息时,也必须指定消息的Routing Key。

  • Exchange 根据消息的 Routing Key 进行判断,只有队列的 通配符 与消息的 Routing Key 相匹配,队列才会接收消息。

生产者代码:

       //5.创建交换机
        String exchangeName = "test_topic";
        channel.exchangeDeclare(exchangeName, BuiltinExchangeType.TOPIC,true,false,false,null);
        //6.创建队列
        //  String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
        String queue1Name = "test_topic_queue1";
        String queue2Name = "test_topic_queue2";
        channel.queueDeclare(queue1Name,true,false,false,null);
        channel.queueDeclare(queue2Name,true,false,false,null);
        //7.绑定队列和交换机	指定通配符
        channel.queueBind(queue1Name,exchangeName,"#.error");
        channel.queueBind(queue1Name,exchangeName,"order.*");
        channel.queueBind(queue2Name,exchangeName,"*.*");
        // 参数: 1. 队列名称 2. 交换机名称  3. routingKey 路由键,绑定规则  fanout 为 "";
        //8.发送消息
        String body = "日志信息,Routing模式开启";
        String error = "日志信息,Routing模式开启种出现错误";
        channel.basicPublish(exchangeName,"order.info",null,body.getBytes());
        channel.basicPublish(exchangeName,"sql.log.error",null,error.getBytes());

"#.error" 可以匹配 “sql.log.error” ,因为 # 可以代替零或多个单词。

五、Spring整合RabbitMQ

六、Springboot整合RabbitMQ

配置文件:application.yml

spring:
  rabbitmq:
    host: 120.79.155.127
    port: 5672
    username: root
    password: ****
    virtual-host: /sparks

生产生配置类:

  • 1.配置交换机
  • 2.配置队列
  • 3.绑定交换机和队列
@Configuration
public class RabbitMQConfig {
    public static final String EXCHANGE_NAME = "boot_topic_exchange";
    public static final String QUEUE_NAME = "boot_queue";
    //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.队列和交换机绑定
    @Bean
    public Binding bindQueueExchange(@Qualifier("bootQueue") Queue queue,@Qualifier("bootExchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("boot.#").noargs();
    }
}

生产者代码测试:

@SpringBootTest
public class ProducerTest {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSend() {
        rabbitTemplate.convertAndSend(RabbitMQConfig.EXCHANGE_NAME,"boot.test","boot rabbit hello");
    }
}

生产端直接注入RabbitTemplate完成消息发送。

消费端:
配置文件:

spring:
  rabbitmq:
    host: 120.79.155.127
    port: 5672
    username: root
    password: ****
    virtual-host: /sparks
@Component
public class RabbitMQListener {

    @RabbitListener(queues = "boot_queue")
    public void ListenerQueue(Message message) {
        System.out.println(new String(message.getBody()));
    }
}

消费端直接使用 @RabbitListener 完成消息接收。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值