消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象。
ds:消息其实指的就是数据,什么“张三”、“李四”、“王五”、“赵六”等这些都是数据,都是消息。而它说的数据,并不是我们传统中所说的数据,而用在应用程序之间传递的数据,即消息。也就是说A系统和B系统之间传送的数据,我们通常叫做消息。消息可以是简单的字符串,如“张三”、“李四”、“王五”、“赵六”等;也可以是非常复杂的数据,如一个User.java对象;甚至可以是,一个集合,如ArrayList
总的来说,什么东西都有可能是消息,因为它就是数据。
消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,由消息系统来确保消息的可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发布者和使用者都不用知道对方的存在。
ds:也就是说,消息发布者只管发布消息到mq中,而不用管到底谁来取。而消息的使用者,只要去队列中取数据就可以了,它不用管这个消息是谁发布的。
而“消息队列(Message Queue)是一种应用间的通信方式”,这句话表明了:我们的消息要遵守队列的概念。队列的核心思想是:先进先出,后进后出,因此先进队列的消息肯定先出队列,而后进的消息肯定后出队列,消息也是不能插队的。
总的来说,也可以把消息队列想象成一个容器。
2、为什么要使用消息队列
ds:消息是应用程序之间传送的消息(数据),那我们dubbo、redis、httpclient都能做到,即A应用把数据传递到B应用上而已,转子,为什么要使用消息队列来做呢?
从上面的描述中可以看出消息队列是一种应用间的异步协作机制,那什么时候需要使用 MQ 呢?ds:怎么就是“异步协作机制”了?即消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。就像平时的快递小哥只管把快递放到菜鸟驿站就行了,你不需要是哪个快递小哥、叫什么名字;反之,快递小哥也不需要知道哪个人过来领取快递、叫什么名字。这个快递的放置和领取,就是一种典型的异步协作机制。而“菜鸟驿站(容器)”,就相当于一个容器,就相当于我们的消息(快递)队列。
一旦实现“异步协作机制”以后,就会有一个特点叫做解耦合。
以常见的订单系统为例,用户点击【下单】按钮之后的业务逻辑可能包括:扣减库存、生成相应单据、发红包、发短信通知。在业务发展初期这些逻辑可能放在一起同步执行,随着业务的发展订单量增长,需要提升系统服务的性能,这时可以将一些不需要立即生效的操作拆分出来异步执行,比如发放红包、发短信通知等。这种场景下就可以用 MQ ,在下单的主流程(比如扣减库存、生成相应单据)完成之后发送一条消息到 MQ 让主流程快速完结,而由另外的单独线程拉取MQ的消息(或者由 MQ 推送消息),当发现 MQ 中有发红包或发短信之类的消息时,执行相应的业务逻辑。
以上是用于业务解耦的情况,其它常见场景包括最终一致性、广播、错峰流控等等。
ds:
首先,一个业务逻辑可能包含:扣减库存、生成相应单据、发红包、发短信通知、发邮件等。而如,发短信要去调用第三方的短信接口,而这些接口可能都会很慢。再如,发邮件业务。发短信要去调用第三方的邮件服务器接口,这也都可能非常慢的。如果说用户点击一个按钮,应用就要把上面所说的所有业务都做一个遍,那么这个应用程序的效率就会非常非常的低。
其次,有些业务并不是非常重要的:比如,发邮件业务,邮件发不发都可以。只要有短信到手机就可以了吧,大家手机都会在身边的。相反,这些业务中最最重要的两个业务(主要业务逻辑)是什么?那就是扣减库存、生成相应单据。什么“发红包、发短信通知、发邮件”等,都是其次吧。也就是说,用户点击按钮的时候,我们先把主要的业务逻辑,即扣减库存、生成相应单据处理完成。而次要的业务逻辑,即发红包、发短信通知、发邮件,你爱什么时候完成就什么时候完成,异步去做就行了。
3、解耦(异步协作机制)、场景包括最终一致性、广播、错峰流控等等图1:消息队列运行流程
图2、图3:异步协作机制
ds:异步协作机制的场景2:解耦
如上图所示,其实这个时候(在第2步)早就完成对用户的响应了。 如上图所示,这个时候就是异步去做的,这时候我们发红包、发短信、发邮件这3步(需要3秒)相当于“省掉”了。如果业务逻辑中有更多的次要业务,我们都用队列的方式去做,那么就会“省掉”更多时间,达到更快速地响应用户,提高用户体验。
如在生活中,快递员只要把快递放置的位置(如菜鸟驿站)告诉你(如短信),然后他就走了,至于你什么取都可以。快递员只管把快递往那里放,他不关心谁来取,什么时候取。我们也是,只管取快递,不用管快递员是男的、女的,是高、是矮,是胖、是瘦。以上模式,就是异步协作机制。
反过来想,如果是同步机制的话:这就要求快递员把快递送到你楼下,然后你亲自下楼拿,做到一手交钱一手交货。这效率,就慢很多。
ds:异步协作机制的场景2:最终一致性
如上图所示,以前我们使用同步完成,我们可以使用数据库的事务去实现,可这5个业务(扣减库存、生成相应单据、发红包、发短信通知、发邮件)要么全部完成,要么全部回滚到原来的状态。而现在,主要业务逻辑(扣减库存、生成相应单据)完成以后,我们就会入库了。但将要业务逻辑(发红包、发短信通知、发邮件),不一定能够正常完成。
“最终一致性”的意思正是如此,即主要业务逻辑完成就行了,次要的业务逻辑能不能完成不管。反之,那就是“强一致性”,即以前的写法:在一段代码中使用事务保证5个业务一起完成或一起回滚。
ds:异步协作机制的场景3:广播
广播是一种机制,比如服务器发布一条消息,所以的客户端都能获取到这条消息,这就是广播。
ds:异步协作机制的场景4:错峰控制
错峰控制,是做流量削峰用的。即当你的(访问)流量太高的时候,可以使用队列降低峰值,以避免服务器由于压力过大而宕机。
二、体系的组织结构设计、工作原理、运行流程、实现方法RabbitMQ的消息发送和接收机制
所有 MQ 产品从模型抽象上来说都是一样的过程:消费者(consumer)订阅(ds:监听)某个队列。生产者(producer)创建消息,然后发布到队列(queue)中,最后将消息发送到监听的消费者。
上面是MQ的基本抽象模型,但是不同的MQ产品有有者不同的机制,RabbitMQ实际基于AMQP协议的一个开源实现,因此RabbitMQ内部也是AMQP的基本概念。
RabbitMQ的内部接收如下(ds:AMQP的基本概念长这个样子):
各个角色关系说明:
- ds:一个Broker中,可以有若干个Virtual Host。ds:一个Virtual Host中,可以有若干个Exchange、若干个队列。ds:Exchange与队列的Binding(绑定)规则:一个Exchange,会绑定到一个队列去。
ds:生产者provider,工作流程
- 首先,生产者将消息写入到Broker中。其次,进入到Broker中的某个Virtual Host中,即指定好命名空间。接着,进入到指定的Virtual Host中,并指定将消息存入到某个Exchange中。最后,Exchange根据绑定规则将消息写入到某个队列中,即消息最终会在队列中进行存放。在这里队列相当于一个容器,是专门用来存放消息的。
经过以上4步以后,生产者的那部分操作就算完成了。只要生产者完成操作以后,那么这个时候它就可以立即访问。
ds:消费者consumer,工作流程
- 首先,consumer需要通过连接
1、Message
消息,消息是不具体的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
2、Publisher
消息的生产者,也是一个向交换器发布消息的客户端应用程序。
3、Exchange
交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
ds:一个Virtual Host中可以有若干个Exchange。
4、Binding
绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
5、Queue
消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
6、Connection
网络连接,比如一个TCP连接。
7、Channel
信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP 都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP连接。
8、Consumer
消息的消费者,表示一个从消息队列中取得消息的客户端应用程序。
9、Virtual Host(上图蓝色区域)
虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制。vhost 是 AMQP概念的基础,必须在连接时指定,RabbitMQ 默认的vhost 是 / 。
ds:Virtual Host,即命名空间,说白了就是一个文件夹呗。
ds:在一个Broker中,可以有若干个Virtual Host。
10、Broker(上图的黄色区域)
表示消息队列服务器实体。
ds:Broker,即你启动的那个RabbitMQ。
三、具体1:环境搭建 序言一般来说安装 RabbitMQ 之前要安装 Erlang ,可以去Erlang官网下载。接着去RabbitMQ官网下载安装包,之后解压缩即可。
Erlang官方下载地址:Downloads - Erlang/OTP
RabbitMQ官方下载地址:Downloading and Installing RabbitMQ — RabbitMQ
1、安装前的准备:安装Erlang语言环境第一步:依赖包安装
ds:要想安装RabbitMQ,首先得安装Erlang。要安装Erlang,首先得先安装Erlang库(依赖包)。
安装RabbitMQ之前必须要先安装所需要的依赖包可以使用下面的一次性安装命令
yum install gcc glibc-devel make ncurses-devel openssl-devel xmlto -y
第二步:安装Erlang
1、将Erlang源代码包otp_src_19.3.tar.gz上传到Linux的/home目录下
2、解压erlang 源码包
tar -zxvf otp_src_19.3.tar.gz
3、手动创建erlang 的安装目录
mkdir /usr/local/erlang
4、进入erlang的解压目录
cd otp_src_19.3
5、配置erlang的安装信息
./configure --prefix=/usr/local/erlang --without-javac
6、编译并安装
make && make install
7、配置环境变量
vim /etc/profile
8、将这些配置填写到profile文件的最后
ERL_HOME=/usr/local/erlang
PATH=$ERL_HOME/bin:$PATH
export ERL_HOME PATH
9、启动环境变量配置文件
source /etc/profile
10、查看当前Erlang的版本号
erl -version
2、安装RabbitMQ1、将RabbitMQ安装包rabbitmq-server-3.7.2-1.el7.noarch.rpm上传到/home目录
2、安装RabbitMQ
rpm -ivh --nodeps rabbitmq-server-3.7.2-1.el7.noarch.rpm
四、具体2:RabbitMQ管控台界面详解 1、Overview 2、Admin(不用关注) 五、其它基体 1、RabbitMQ特点RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。ds: AMQP 的开源实现有10几20个都不止。
AMQP :Advanced Message Queue,高级消息队列协议。它是应用层协议的一个开放标准,为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,并不受产品、开发语言等条件的限制。
RabbitMQ 最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。具体特点包括:
1、可靠性(Reliability)
RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。
2、灵活的路由(Flexible Routing)
在消息进入队列之前,通过 Exchange 来路由消息的。对于典型的路由功能,RabbitMQ 已经提供了一些内置的 Exchange 来实现。针对更复杂的路由功能,可以将多个 Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。
3、 消息集群(Clustering)
多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker 。
3、 高可用(Highly Available Queues)
队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。
4、多种协议(Multi-protocol)
RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等等。
5、多语言客户端(Many Clients)
RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby 等等。
6、 管理界面(Management UI)
RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。
7、 跟踪机制(Tracing)
如果消息异常,RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。
2、什么是路由、路由器?
ds:路由就是转发的意思。像我们使用的路由器,什么是路由器呀?路由器就是将我们的信号转发到我们的计算机中去,或者反方向将我们的计算机转发到互联网去。这就是所谓的路由器的一个作用,有了路由器就可以将网络信息转发到不同的计算机中去。
3、RabbitMQ与kafuka的区别ds:RabbitMQ和kafuka有着天壤之别,kafuka的效率比RabbitMQ要高,但是数据不安全。RabbitMQ的效率虽然没有kafuka效率高,但是数据是安全的。所以,我们在不同的领域中,要使用不同的消息队列。
4、Erlang与java的区别与联系ds:因为Erlang是RabbitMQ的开发语言,所以要安装RabbitMQ,首先得先去安装Erlang语言环境。Erlang语言有点类似于我们的java语言,也需要安装它自己的“jdk”,即像jdk一样去安装Erlang语言环境才可以。
5、.rpm(linux)与.exe(windows)的区别ds:在linux中的.rpm可执行文件(可执行安装包文件),相当于windows中的.exe可执行文件。我们在linux中,直接运行.rpm,就可以安装当前的软件了。
6、命名空间是什么?ds:命名空间相当于我们windows中的一个文件夹。
7、RabbitMQ常用命令(1)启动和关闭
1、启动RabbitMQ
rabbitmq-server start &
注意:这里可能会出现错误,错误原因是/var/lib/rabbitmq/.erlang.cookie文件权限不够。
解决方案对这个文件授权:
chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
ds:第一个问题:.erlang.cookie的所属用户和用户组不是rabbitmq,启动不了。
chmod 400 /var/lib/rabbitmq/.erlang.cookie
ds:第二个问题,.erlang.cookie没有只读权限,启动不了。
2、停止服务
rabbitmqctl stop
3、查看RabbitMQ服务
ps -ef|grep rabbitmq
(2)插件管理
1、添加插件
rabbitmq-plugins enable {插件名}
2、删除插件
rabbitmq-plugins disable {插件名}
注意:RabbitMQ启动以后可以使用浏览器进入管控台但是默认情况RabbitMQ不允许直接使用浏览器浏览器进行访问因此必须添加插件
rabbitmq-plugins enable rabbitmq_management
3、使用浏览器访问管控台http://RabbitMQ服务器IP:15672
http://192.168.71.128:15672 用户名:guest,密码:guest
(3)用户管理
RabbitMQ安装成功后使用默认用户名guest登录
账号:guest
密码:guest
注意:这里guest只允许本机登录访问需要创建用户并授权远程访问命令如下
添加用户:rabbitmqctl add_user {username} {password}
rabbitmqctl add_user root root
删除用户:rabbitmqctl delete_user {username}
修改密码:rabbitmqctl change_password {username} {newpassword}
rabbitmqctl change_password root 123456
设置用户角色:rabbitmqctl set_user_tags {username} {tag}
rabbitmqctl set_user_tags root administrator
tag参数表示用户角色取值为:management ,monitoring ,policymaker administrator
各角色详解:
management
用户可以通过AMQP做的任何事外加:
列出自己可以通过AMQP登入的virtual hosts
查看自己的virtual hosts中的queues, exchanges 和 bindings
查看和关闭自己的channels 和 connections
查看有关自己的virtual hosts的“全局”的统计信息,包含其他用户在这些virtual hosts中的活动。
policymaker
management可以做的任何事外加:
查看、创建和删除自己的virtual hosts所属的policies和parameters
monitoring
management可以做的任何事外加:
列出所有virtual hosts,包括他们不能登录的virtual hosts
查看其他用户的connections和channels
查看节点级别的数据如clustering和memory使用情况
查看真正的关于所有virtual hosts的全局的统计信息
administrator
policymaker和monitoring可以做的任何事外加:
创建和删除virtual hosts
查看、创建和删除users
查看创建和删除permissions
关闭其他用户的connections
(4)权限管理(对队列的操作权限,如访问权限)
1、授权命令:rabbitmqctl set_permissions [-p vhostpath] {user} {conf} {write} {read}
-p vhostpath :用于指定一个资源的命名空间,例如 –p / 表示根路径命名空间
user:用于指定要为哪个用户授权填写用户名
conf:一个正则表达式match哪些配置资源能够被该用户配置。
write:一个正则表达式match哪些配置资源能够被该用户读。
read:一个正则表达式match哪些配置资源能够被该用户访问。
例如:
rabbitmqctl set_permissions -p / root '.*' '.*' '.*'
用于设置root用户拥有对所有资源的 读写配置权限
2、查看用户权限 rabbitmqctl list_permissions [vhostpath]
例如
查看根径经下的所有用户权限
rabbitmqctl list_permissions
查看指定命名空间下的所有用户权限
rabbitmqctl list_permissions /abc
3、查看指定用户下的权限rabbitmqctl list_user_permissions {username}
例如
查看root用户下的权限
rabbitmqctl list_user_permissions root
4、清除用户权限rabbitmqctl clear_permissions {username}
例如:
清除root用户的权限
rabbitmqctl clear_permissions root
(5)vhost管理
vhost是RabbitMQ中的一个命名空间,可以限制消息的存放位置利用这个命名空间可以进行权限的控制有点类似Windows中的文件夹一样,在不同的文件夹中存放不同的文件。
1、添加vhost: rabbitmqctl add vhost {name}
例如
rabbitmqctl add vhost bjpowernode
2、删除vhost:rabbitmqctl delete vhost {name}
例如
rabbitmqctl delete vhost bjpowernode



