RabbitMQ学习笔记

1、引言

什么是MQ

MQ(Message Quene):消息队列,通过典型的生产者消费者模型不断向消息队列中生产消息,消费者不断从队列中获取消息。因为消息的生产和消费是异步的,而且只关系消息的发送和接收,没有业务逻辑的侵入,轻松地实现系统间解耦。别名为消息中间件,通过利用高效可靠的消息传递机制进行平台无关的数据交流,并给予数据通信进行分布式系统的集成

AMQP 协议

AMQP(advanced message queuing protocol)在2003年时被提出,最早用于解决金融领不同平台之间的消息传递交互问题。顾名思义,AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议)。这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式。这使得实现了AMQP的provider天然性就是跨平台的。以下是AMQP协议模型:

在这里插入图片描述

在这里插入图片描述

不同MQ特点

  • ActiveMQ:是Apache出品,是最流行,能力强劲的开源消息总线。它是一个完全支持JMS规范的消息中间件。有丰富的API,多种集群架构模式让ActiveMQ称为老牌成熟的消息中间件,中小企业使用广泛
  • Kafka:是LinkedIn开源的分布式发布-订阅消息系统,目前属于Apache顶级项目。主要特点是基于Pull的模式处理消息消费,追求吞吐量。一开始的目的就是用于日志收集和传输,0.8版本之后开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务
  • RocketMQ:是阿里开源的消息中间件,纯java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ起源于Kafka,对消息的可靠传输及事务性做了优化,在阿里被广泛用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景
  • RabbitMQ:使用Erlang语言开发的消息队列系统。基于AMQP协议来实现。主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求在其次

RabbitMQ比Kafka更可靠,Kafka更适合IO高吞吐的处理,一般应用在大数据日志处理或对实时性(少量延迟),可靠性(少量丢失数据)要求稍低的场景使用,比如ELK日志收集

RabbitMQ安装

RabbitMQ官网

RabbitMQ下载 (注意与erlang版本对应关系)

Releases · rabbitmq/rabbitmq-server (github.com)

Releases · rabbitmq/erlang-rpm (github.com)

# 1.将安装包上传到服务器
erlang-23.3.1-1.el7.x86_64.rpm 
rabbitmq-server-3.8.13-1.el7.noarch.rpm

# 2.安装erlang依赖包
yum install -y erlang-23.3.1-1.el7.x86_64.rpm

# 3.安装rabbitmq
yum install -y rabbitmq-server-3.8.13-1.el7.noarch.rpm

# 4.配置文件
#见下方配置文件说明

# 5.修改配置文件
loopback_users.guest = false

# 6.启动rabbitmq中的插件管理
rabbitmq-plugins enable rabbitmq_management

# 7.启动rabbitmq
systemctl start rabbitmq-server # 启动rabbitmq服务
systemctl restart rabbitmq-server # 重启服务
systemctl stop rabbitmq-server  # 停止服务

# 8.查看rabbitmq状态
systemctl status rabbitmq-server

# 9.访问rabbitmq的web管理界面
#开放端口访问
firewall-cmd --add-port=15672/tcp --permanent
firewall-cmd --reload
http://192.168.232.134:15672/  #访问

# 10.初始登录
guest guest

rabbitmq-server-3.8.13配置文件

安装之后/etc/rabbitmq/目录下没有rabbitmq的配置文件,在/usr/share/doc/rabbitmq-server-3.8.13/目录下也没有提供配置文件模板

可以到github上下载将其拷贝到目录下

https://github.com/rabbitmq/rabbitmq-server/tree/v3.8.x/deps/rabbit/docs

因为没有多少配置,此处直接在/etc/rabbitmq/目录下新建rabbit.conf,添加

loopback_users.guest = false

更多详细配置查看Configuration — RabbitMQ

登录成功显示
在这里插入图片描述

2、RabbitMQ配置

web界面连接rabbitmq端口:15672

Java连接rabbitmq端口:5672

RabbitMQ管理命令行

# 1.服务启动相关
systemctl start|restart|stop|status rabbitmq-server

# 2.管理命令行  用来在不使用web管理界面情况下命令操作RabbitMQ
rabbitmqctl  help  #查看支持的命令

# 3.插件管理命令行
rabbitmq-plugins enable|list|disable 

web管理界面介绍

导航栏介绍

在这里插入图片描述

常见概念

Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程。

Virtual Host:虚拟主机,类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,但是权限控制的最小粒度是Virtual Host

Connections:无论生产者还是消费者,都需要与RabbitMQ建立连接后才能完成消息的生产和消费,在这里可以查看连接情况。对于RabbitMQ而言,其实就是一个位于客户端和Broker之间的TCP连接。

Channels:通道,建立连接后会形成通道,消息的传递获取依赖于通道

Exchanges:交换机,用来实现消息的路由。接收生产者发送的消息,并根据一定规则将消息路由给服务器中的队列

Message Queues:消息队列,消息存放在队列中,等待消费,消费后被移除队列

Message:由Header和Body组成。Header是由生产者添加的各种属性的集合,包括Message是否被持久化、由哪个Message Queue接受、优先级是多少等。而Body是真正需要传输的APP数据。

Admin用户管理和虚拟主机管理
创建用户

在这里插入图片描述

Tags选项用户可选类型

  • Admin:超级管理员,可登录管理控制台,可查看所有信息,并且可以对用户,策略(policy)进行操作
  • Monitoring:监控者,可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)
  • Policymaker:策略制定者,可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)
  • Management:普通管理者, 仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理
  • 其他:无法登陆管理控制台,通常就是普通的生产者和消费者。
创建虚拟主机

为了让各个用户可以互不干扰的工作,RabbitMQ添加了虚拟主机(Virtual Hosts)的概念。其实就是一个独立的访问路径,不同用户使用不同路径,各自有自己的队列、交换机,互相不会影响。在这里插入图片描述

绑定虚拟主机和用户

在这里插入图片描述
在这里插入图片描述

3、RabbitMQ支持的消息模型

RabbitMQ Tutorials — 官网介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-07wbxuy5-1620285282152)(C:\Users\Blanc\AppData\Roaming\Typora\typora-user-images\image-20210427160053810.png)]

添加端口访问

firewall-cmd --add-port=5672/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-all

rabbitmq依赖

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

第一种-基本模型(直连)

概述

img

P:生产者,要发送消息的程序

C:消费者,等待接收消息的程序

Queue:消息队列,图中红色部分。实质上是一个大的消息缓冲区。类似一个邮箱,可以缓存消息;生产者向其中投递消息,消费者从其中取出消息。遵循先进先出原则

开发工具类
public class RabbitmqUtils {
   
    private static final ConnectionFactory connectionFactory;
    static {
   
        //创建连接mq的连接工厂对象,重量级对象,类加载时创建一次即可
        connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq的主机
        connectionFactory.setHost("192.168.232.134");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接的虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置访问虚拟主机的用户名和密码
        connectionFactory.setUsername("alice");
        connectionFactory.setPassword("123");
    }

    //获取连接对象
    public static Connection getConnection(){
   
        try {
   
            return connectionFactory.newConnection();
        } catch (IOException | TimeoutException e) {
   
            e.printStackTrace();
        }
        return null;
    }

    //关闭通道和连接
    public static void close(Channel channel, Connection connection){
   
        if(channel != null){
   
            try {
   
                channel.close();
            } catch (IOException | TimeoutException e) {
   
                e.printStackTrace();
            }
        }
        if(connection != null){
   
            try {
   
                connection.close();
            } catch (IOException e) {
   
                e.printStackTrace();
            }
        }
    }
}
开发生产者
public class Provider {
   
    public static void main(String[] args) {
   
        Connection connection = null;
        Channel channel = null;

        try {
   
            //获取连接对象
            connection = RabbitmqUtils.getConnection();
            //获取通道
            if (connection != null) {
   
                channel = connection.createChannel();
                //通道绑定对应消息队列
                /*
                 * 参数1 queue:队列名称(不存在自动创建)
                 * 参数2 durable:用来定义队列特性是否需要持久化(为true该队列将在服务器重启后保留下来,持久化到硬盘中)
                 * 参数3 exclusive:是否独占队列(为true仅限此连接)
                 * 参数4 autoDelete:是否在消费完成后自动删除队列
                 * 参数5 arguments:队列的其他属性(构造参数)
                 * */
                channel.queueDeclare("hello",false,false,false,null);

                //发布消息
                /*
                 * 参数1 exchange:要将消息发布到的交换机
                 * 餐数2 routingKey:路由键,指定队列
                 * 参数3 props:消息的其他属性
                 * 参数4 body:消息具体内容
                 * */
                String message = "hello rabbitmq";
                channel.basicPublish("","hello",null,message.getBytes());
            }
        } catch (IOException e) {
   
            e.printStackTrace();
        } finally {
   
            System.out.println("生产者发布消息完成......");
            RabbitmqUtils.close(channel,connection);
        }
    }
}

执行生产者测试方法,队列中成功添加进消息
在这里插入图片描述

开发消费者
public class Consumer {
   
    public static void main(String[] args) {
   
        Connection connection = null;
        Channel channel = null;

        try {
   
            //获取连接对象
            connection = RabbitmqUtils.getConnection();
            //获取通道
            if (connection != null) {
   
                channel = connection.createChannel();
                //通道绑定对应消息队列
                /*
                 * 参数1 queue:队列名称(不存在自动创建)
                 * 参数2 durable:用来定义队列特性是否需要持久化(为true该队列将在服务器重启后保留下来)
                 * 参数3 exclusive:是否独占队列(为true仅限此连接)
                 * 参数4 autoDelete:是否在消费完成不再使用后自动删除队列
                 * 参数5 arguments:队列的其他属性(构造参数)
                 * */
                channel.queueDeclare("hello",false,false,false,null);

                //消费消息
                DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
   
                    //获取消息并且处理。此方法类似于事件监听,有消息时会被自动调用
                    @Override
                    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
   
                        System.out.println("message:"+new String(body));  //body即消息体
                    }
                };
                /*
                 * 参数1 queue:队列名称
                 * 参数2 autoAck:开启消息的自动确认机制
                 * 参数3 Consumer callback:消费时的回调接口
                 * */
                channel.basicConsume("hello",true, defaultConsumer);
            }
        } catch (IOException e) {
   
            e.printStackTrace(
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值