在我们秒杀抢购商品的时候,系统会提醒我们稍等排队中,而不是像几年前一样页面卡死或报错给用户。像这种排队结算就用到了消息队列机制,放入通道里面一个一个结算处理,而不是某个时间断突然涌入大批量的查询新增把数据库给搞宕机,所以RabbitMQ本质上起到的作用就是削峰填谷,为业务保驾护航。
MQ简介
MQ 全称为Message Queue, 消息队列。是一种应用程序对应用程序的通信方法。
应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间,通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信。队列的使用除去了接收和发送应用程序,同时执行的要求。
在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式,大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
核心功能
削峰
MQ的分类
P2P模式(Point-to-Point安全)
P2P模式包含三个角色:
1.消息队列(Queue)、
2.发送者(Sender)、
3.接收者(Receiver)。
每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到它们被消费或超时。
P2P的特点如下:
• 每个消息只有一个消费者(Consumer),即一旦被消费,消息就不再在消息队列中
• 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息之后,不管接收者有没有正在运行它不会影响到消息被发送到队列
• 接收者在成功接收消息之后,需向队列应答成功。
• 如果希望发送的每个消息都会被成功处理的话,那么需要P2P模式
Pub/Sub模式(并发)Publish/Subscribe
Pub/Sub模式包含三个角色:主题(Topic)、发布者(Publisher)、订阅者(Subscriber) 。多个发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。Pub/Sub的特点如下:
• 每个消息可以有多个消费者
• 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息
• 为了消费消息,订阅者必须保持运行的状态
• 如果希望发送的消息可以不被做任何处理、或者只被一个消息者处理、或者可以被多个消费者处理的话,那么可以采用Pub/Sub模型
AMQP介绍
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。
RabbitMQ应用场景
对于一个大型的软件系统来说,它会有很多的组件或者说模块或者说子系统(subsystem or Component or submodule)。那么这些模块的如何通信?这和传统的IPC有很大的区别。传统的IPC很多都是在单一系统上的,模块耦合性很大,不适合扩展(Scalability);如果使用socket那么不同的模块的确可以部署到不同的机器上,但是还是有很多问题需要解决。
比如:
1)信息的发送者和接收者如何维持这个连接,如果一方的连接中断,这期间的数据会不会丢失?
2)如何降低发送者和接收者的耦合度?
3)如何让Priority高的接收者先接到数据?
4)如何做到load balance?有效均衡接收者的负载?
5)如何有效的将数据发送到相关的接收者?也就是说将接收者subscribe 处理不同的数据,如何做有效的filter。
6)如何做到可扩展,甚至将这个通信模块发到cluster上?
7)如何保证接收者接收到了完整,正确的数据? AMQP协议解决了以上的问题,而RabbitMQ实现了AMQP。
RabbitMQ架构图示
RabbitMQ从整体上来看是一个典型的生产者消费者模型,主要负责接收、存储和转发消息
Rabbit MQ的通信过程
三台主机相互通信 解析
192.168.238.129 rabbitmq1
192.168.238.130 rabbitmq2
192.168.238.131 rabbitmq3
使用下面命令shell终端exit退出在登陆更新名称,`一定要更新`
hostnamectl set-hostname rabbitmq1
软件部署:
安装erlang
vim /etc/yum.repos.d/erlang.repo
[rabbitmq_erlang]
name=rabbitmq_erlang
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
[rabbitmq_erlang-source]
name=rabbitmq_erlang-source
baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/SRPMS
repo_gpgcheck=1
gpgcheck=0
enabled=1
gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
metadata_expire=300
yum -y install erlang
安装rabbitmq
直接下载rpm包
wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.13/rabbitmq-server-3.7.13-1.el7.noarch.rpm
yum -y install rabbitmq-server-3.7.13-1.el7.noarch.rpm
修改配置文件:
cp /usr/share/doc/rabbitmq-server-3.7.13/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config
vim /etc/rabbitmq/rabbitmq.config
##61行去掉注释%%和,
{lopback_user, []}
安装插件并启动服务
web管理界面工具
rabbitmq-plugins enable rabbitmq_management
systemctl restart rabbitmq-server
查看状态
rabbitmqctl cluster_status
[root@rabbitmq1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1]}]},
{running_nodes,[rabbit@rabbitmq1]},
{cluster_name,<<"rabbit@rabbitmq1">>},
{partitions,[]},
{alarms,[{rabbit@rabbitmq1,[]}]}
访问测试:
http://IPADDER:15672
默认密码:guest/guest
在rabbitmq1的基础上
先停掉rabbitmq1systemctl stop rabbitmq-server
然后对rabbitmq2、rabbitmq3安装rabbitMQ erlang以及修改配置文件rabbitmq.config ****所有节点安装rabbitmq erlang****
所有节点并导入 rabbitmq-plugins enable rabbitmq_management
一定要保证三台机器的cookie内容一致
找到erlang cookie文件的位置,源码包部署一般会存在.erlang.cookie文件;rpm包部署一般是在/var/lib/rabbitmq/.erlang.cookie。将 node1 的该文件使用rsync或者是scp复制到 node2、node3,文件权限需要是400。
scp -r /var/lib/rabbitmq/.erlang.cookie rabbitmq2:/var/lib/rabbitmq/.erlang.cookie
scp -r /var/lib/rabbitmq/.erlang.cookie rabbitmq3:/var/lib/rabbitmq/.erlang.cookie
cat /var/lib/rabbitmq/.erlang.cookie #查看
rabbitmq2和rabbitmq3
systemctl restart rabbitmq-server
rabbitmq2/rabbitmq3测试:
rabbitmqctl cluster_status
root@rabbitmq1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1]}]},
{running_nodes,[rabbit@rabbitmq1]},
{cluster_name,<<"rabbit@rabbitmq1">>},
{partitions,[]},
{alarms,[{rabbit@rabbitmq1,[]}]}]
Cluster status of node rabbit@rabbitmq1
每台主机看到的只有一个的server信息。目前尚未组合成集群
rabbitmq2/rabbitmq3
rabbitmqctl add_user admin admin
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
rabbitmqctl set_user_tags admin administrator
对rabbitmq1/rabbitmq2访问测试:
http://ip:15672
账号:admin
密码:admin
测试各主机还是单机rabbitmqctl rabbitmq_status 测试
简介
rabbitmq-server 启动时,会一起启动:节点和应用,它预先设置RabbitMQ应用为standalone(脱机)模式。要将一个节点加入到现有的集群中,你需要停止这个应用,并将节点设置为原始状态。如果使用rabbitmqctl stop,应用和节点都将被关闭。所以使用rabbitmqctl stop_app仅仅关闭应用。(停应用,不停止节点)
对rabbitmq1/rabbitmq2操作:磁盘节点
rabbitmqctl stop_app 仅停止应用,不关闭节点
rabbitmqctl join_cluster rabbit@rabbitmq1
rabbitmqctl start_app
rabbitmq1节点1查看
[root@rabbitmq1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq1 ...
[{nodes,[{disc,[rabbit@rabbitmq1,rabbit@rabbitmq2]}]},
{running_nodes,[rabbit@rabbitmq2,rabbit@rabbitmq1]},
{cluster_name,<<"rabbit@rabbitmq1">>},
{partitions,[]},
{alarms,[{rabbit@rabbitmq2,[]},{rabbit@rabbitmq1,[]}]}]