目录
一、什么是MQ
MQ
(message queue)
消息队列
,其本质是个队列,
FIFO 先入先出
,只不过队列中存放的内容是
message
而已,还是一种
跨进程
的
通信机制
,用于上下游
传递消息
。在互联网架构中,MQ 是一种非常常见的上下游“
逻辑解耦
+
物理解耦
”的
消息通信服务
。使用了 MQ 之后,消息发送上游只需要依赖 MQ,不用依赖其他服务。
MQ的分类:ActiveMQ、Kafka、RocketMQ、RabbitMQ
二、MQ的作用
1.
流量消峰
举个例子,如果订单系统最多能处理一万次订单,这个处理能力应付正常时段的下单时绰绰有余,正常时段我们下单一秒后就能返回结果。但是在高峰期,如果有两万次下单操作系统是处理不了的,只能
限制
订单超过一万后不允许用户下单。
若使用
消息队列
做
缓冲
,我们就可以
取消
这个
限制
,把一秒内下的订单
分散
成
一段时间
来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作,但是比不能下单的体验要好。
2.
应用解耦
以电商应用为例,应用中有
订单系统
、
库存系统
、
物流系统
、
支付系统
。用户创建订单后,如果
耦合调用
库存系统、物流系统、支付系统,任何一个
子系统
出了
故障
,都会造成
下单操作
异常
。当转变成基于
消息队列
的方式后,系统间
调用
的问题会减少很多,比如
物流系统
因为发生
故障
,需要几分钟来修复。在这几分钟的时间里,
物流系统
要处理的内存被
缓存
在消息队列中,用户的下单操作可以
正常完成
。当
物流系统
恢复
后,
继续处理
订单信息即可,而用户感受不到物流系统的故障,提升系统的
可用性
。
3.
异步处理
有些
服务间调用
是
异步
的,例如 A 调用 B,B 需要花费很长时间执行,但是 A 需要知道 B 什么时候可以执行完,以前一般有两种方式,A 过一段时间去
调用
B 的
查询 api
查询。或者 A 提供一个
callback api
, B 执行完之后
调用 api
通知
A 服务。这两种方式都不是很优雅,使用
消息总线
,可以很方便解决这个问题, A 调用 B 服务后,只需要
监听
B 处理完成的
消息
,当 B 处理完成后,会
发送
一条消息给
MQ
,MQ 会将此消息
转发
给 A 服务。这样 A 服务既不用
循环调用
B 的查询 api,也不用提供
callback
api。同样 B 服务也不用做这些操作。A 服务还能及时的得到
异步处理成功
的
消息
。
三、 RabbitMQ 的概念
RabbitMQ 是一个消息中间件:它
接收
并
转发
消息。你可以把它当做一个快递站点,当你要发送一个包 裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑 RabbitMQ 是 一个快递站,一个快递员帮你传递快件。RabbitMQ 与快递站的主要区别在于,它不处理快件而是
接收
,
存储
和
转发
消息数据。
1.
生产者
产生数据发送消息的程序是生产者
2.
交换机
交换机是 RabbitMQ 非常重要的一个部件,一方面它接收来自生产者的消息,另一方面它将消息推送到队列中。交换机必须确切知道
如何处理
它接收到的消息,是将这些消息
推送
到
特定队列
还是
多个队列
,亦或者是把消息
丢弃
,这个得由交换机的类型决定
3.
队列
队列是 RabbitMQ 内部使用的一种数据结构,尽管消息流经 RabbitMQ 和应用程序,但它们只能存储在队列中。队列仅受主机的内存和磁盘限制的约束,本质上是一个大的
消息缓冲区
。许多生产者可 以将消息
发送
到一个队列,许多消费者可以尝试从一个队列
接收
数据。这就是我们使用队列的方式
4.
消费者
消费与接收具有相似的含义。消费者大多时候是一个
等待接收消息
的程序。请注意生产者,消费者和消息中间件很多时候并不在同一机器上。同一个应用程序既可以是生产者又是可以是消费者。
Broker
:接收和分发消息的应用,RabbitMQ Server 就是 Message Broker
Virtual host
:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的
namespace
概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个
vhost
,每个用户在自己的 vhost 创建
exchange/queue
等
Connection
:publisher/consumer 和 broker 之间的
TCP 连接
Channel
:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection 的开销将是巨大的,效率也较低。Channel 是在 connection
内部
建立的
逻辑连接
,如果应用程 序支持多线程,通常每个 thread 创建单独的 channel 进行通讯,AMQP method 包含了 channel id 帮助客户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。
Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销
Exchange
:message 到达 broker 的第一站,根据
分发规则
,匹配查询表中的 routing key,分发 消息到 queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)
Queue
:消息最终被送到这里等待 consumer 取走
Binding
:exchange 和 queue 之间的
虚拟连接
,binding 中可以包含 routing key,
Binding
信息被保存到 exchange 中的查询表中,用于 message 的分发依据
四、RabbitMQ的六大核心部分
simple
简单模式、
work
工作模式、
publish/subscribe
发布订阅、
routing
路由模式、
topic
主题模式(路由模式的一种)、
publisher confirms
发布确认模式
五、CentOS系统下的环境部署
1.官网地址 https://www.rabbitmq.com/download.html
2.文件拷贝到自定义目录下
3.安装文件(分别按照以下顺序安装)
rpm -ivh erlang-21.3-1.el7.x86_64.rpm
yum install socat -y
rpm -ivh rabbitmq-server-3.8.8-1.el7.noarch.rpm
3.常用命令
#添加开机启动 RabbitMQ 服务
chkconfig rabbitmq-server on
#启动服务
/sbin/service rabbitmq-server start
#查看服务状态
/sbin/service rabbitmq-server status
#停止服务(选择执行)
/sbin/service rabbitmq-server stop
#开启 web 管理插件
rabbitmq-plugins enable rabbitmq_management
#访问地址 http://xxx.xxx.xxx.xxx:15672/
#关闭应用的命令
rabbitmqctl stop_app
#清除的命令
rabbitmqctl reset
#重新启动命令
rabbitmqctl start_app
4.添加一个新的用户
#创建账号
rabbitmqctl add_user admin 123
#设置用户角色
rabbitmqctl set_user_tags admin administrator
#设置用户权限
set_permissions -p "/" admin ".*" ".*" ".*"
#当前用户和角色
rabbitmqctl list_users
5.再次利用 admin 用户登录rabbitMQ后台
6.在idea中引入依赖:
<!--rabbitmq 依赖客户端-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.8.0</version>
</dependency>
<!--操作文件流的一个依赖-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>