# MQ简介
MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法,应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们,消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术,排队指的是应用程序通过 队列来通信,队列的使用除去了接收和发送应用程序同时执行的要求
# 什么是RabbitMQ
RabbitMQ是由Erlang语言编写的实现了高级消息队列协议(AMQP)的开源消息代理软件(也可称为 面向消息的中间件),支持Windows、Linux/Unix、MAC OS X操作系统和包括JAVA在内的多种编程语言
AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制
RabbitMQ使用场景:
1. 异步处理
2. 应用解耦
3. 流量削峰
4. 消息通讯
# 安装RabbitMQ
所需软件下载链接:https://pan.baidu.com/s/1gVpsSECRtZ5GUHOwRBe0gQ
提取码:nvt3
```bash
#上传上述所需包
[root@localhost ~]# rz
[root@localhost ~]# ls
anaconda-ks.cfg erlang-18.1-1.el6.x86_64.rpm rabbitmq-server-3.6.6-1.el6.noarch.rpm socat-1.7.3.2-2.el7.x86_64.rpm
#安装RPM包
[root@localhost ~]# yum -y localinstall erlang-18.1-1.el6.x86_64.rpm rabbitmq-server-3.6.6-1.el6.noarch.rpm socat-1.7.3.2-2.el7.x86_64.rpm
#加入开机自启
[root@localhost ~]# chkconfig rabbitmq-server on
#启动rabbitmq
[root@localhost ~]# systemctl start rabbitmq-server
#查看状态
[root@localhost ~]# systemctl status rabbitmq-server
● rabbitmq-server.service - LSB: Enable AMQP service provided by RabbitMQ broker
Loaded: loaded (/etc/rc.d/init.d/rabbitmq-server)
Active: active (running) since Wed 2020-08-05 18:19:37 CST; 7s ago
Docs: man:systemd-sysv-generator(8)
Process: 12401 ExecStart=/etc/rc.d/init.d/rabbitmq-server start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/rabbitmq-server.service
├─12588 /bin/sh /etc/rc.d/init.d/rabbitmq-server start
├─12603 /bin/bash -c ulimit -S -c 0 >/dev/null 2>&1 ; /usr/sbin/rabbitmq-server
└─12604 /bin/sh /usr/sbin/rabbitmq-server
......
#开启rabbitmq的web管理插件,以便可以通过浏览器进行访问
[root@rabbitmq01 ~]# rabbitmq-plugins enable rabbitmq_management
#创建登录用户
#默认WEB管理的登录帐号和密码统一为:guest
[root@rabbitmq01 ~]# rabbitmqctl add_user admin admin
Creating user "admin" ...
#将创建的admin用户添加至administrator组
[root@rabbitmq01 ~]# rabbitmqctl set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ...
```
默认RabbitMQ拥有如下端口号:(一般常用就15672和5672)
|端口|简要说明|
|-------|-------|
|15672|WEB管理界面|
|5672,5671|由AMQP 0-9-1和1.0客户端使用,没有和使用TLS|
|4369|epmd,RabbitMQ节点和CLI工具使用的对等发现服务|
|25672|用于节点间和CLI工具通信(Erlang分发服务器端口)并从动态范围分配(默认情况下限于单个端口,计算为AMQP端口+20000)|
|35672-35682|CLI工具(Erlang分发客户端端口)用于节点间通信并从动态范围(计算为服务器分发端口+10000到服务器分发端口+10010)进行分配|
|61613,61614|没有和使用TLS的STOMP客户端(仅当使用STOMP插件时)|
|1883,8883|如果启用了MQTT插件,则没有使用TLS的MQTT客户端|
|15674|STOMP-over-WebSockets客户端(仅当使用web STOMP插件时)|
|15675|MQTT--over-WebSockets客户端(仅当使用web MTQQ插件时)|
客户端访问: IP:15672


如账号密码无法登陆,执行如下命令
```bash
[root@rabbitmq01 ~]# rabbitmqctl set_user_tags admin administrator
Setting tags for user "guest" to [administrator] ...
[root@rabbitmq01 ~]# rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'
Setting permissions for user "guest" in vhost "/" ...
[root@rabbitmq01 ~]# systemctl restart rabbitmq-server
#测试如果还是无法登陆,则进行Step2
在rabbitmq的配置文件目录下创建一个rabbitmq.config文件
[root@rabbitmq01 rabbitmq]# cat rabbitmq.config
[{rabbit, [{loopback_users, []}]}].
[root@rabbitmq01 ~]# systemctl restart rabbitmq-server
```
# 部署Rabbitmq集群
Rabbitmq集群大概分为两种方式:
- 普通模式:默认的集群模式,消息的尸体只存在一个节点上;
- 镜像模式:把需要的队列做成镜像,存在于多个节点
ha-mode:
all:列队到所有节点;
exatly:随机镜像到其他节点上;
nodes:镜像到指定节点上。
集群节点模式:
- 内存节点:工作在内存上
- 磁盘节点:工作在磁盘上
例外:内存节点和磁盘节点共同存在,提高访问速度的同时增加数据持久化
相比内存节点虽然不写入磁盘,但是它执行比磁盘节点要好,集群中,只需要一个磁盘来保存状态就足够了,如果集群中只有内存节点,那么节点一旦宕机,所有的状态、消息都会丢失,无法实现数据的持久化
## 环境信息
|系统|IP|主机名|
|-------|-------|-------|
|Centos 7|192.168.51.195|rabbitmq01|
|Centos 7|192.168.51.196|rabbitmq02|
|Centos 7|192.168.51.197|rabbitmq03|
|Centos 7|192.168.51.198|rabbitmq04|
其中192.168.5.195就是基于本文上述的单台rabbitmq搭建
## 安装rabbitmq服务
在192.168.1.5和192.168.51.196两个节点上部署,192.168.51.197稍后会用到
```bash
[root@localhost ~]# ls #确认所需RPM包
erlang-18.1-1.el6.x86_64.rpm
rabbitmq-server-3.6.6-1.el6.noarch.rpm
socat-1.7.3.2-2.el7.x86_64.rpm
[root@localhost ~]# yum -y localinstall erlang-18.1-1.el6.x86_64.rpm rabbitmq-server-3.6.6-1.el6.noarch.rpm socat-1.7.3.2-2.el7.x86_64.rpm
#安装RPM包
[root@localhost ~]# chkconfig rabbitmq-server on
#rabbitmq加入开机自启
[root@localhost ~]# systemctl start rabbitmq-server
#启动rabbitmq服务
```
## 配置host文件,并将上述两个节点加入集群
```bash
[root@localhost ~]# echo -e "192.168.51.195 rabbitmq01\n192.168.51.196 rabbitmq02\n192.168.51.197 rabbitmq03\n192.168.51.198 rabbitmq04" >> /etc/hosts
[root@localhost ~]# scp /etc/hosts root@192.168.51.196:/etc/
[root@localhost ~]# scp /etc/hosts root@192.168.51.197:/etc/
[root@localhost ~]# scp /etc/hosts root@192.168.51.198:/etc/
#将rabbitmq01的cookie节点信息复制到其他需要加入群集的节点
#部署群集的时候需要节点cookie信息一致
[root@localhost ~]# scp /var/lib/rabbitmq/.erlang.cookie root@192.168.1.196:/var/lib/rabbitmq/
[root@localhost ~]# scp /var/lib/rabbitmq/.erlang.cookie root@192.168.1.197:/var/lib/rabbitmq/
```
群集中的所有节点都需重启(包括rabbitmq01),若重启过程中卡在某个界面,需手动强制重启
```bash
#重启后,主机名自动更新了,确认了rabbitmq正在运行
[root@rabbitmq01 ~]# ps -ef | grep rabbitmq
```
## rabbitmq01配置群集并将rabbitmq02、03加入01群集
以下操作可以根据主机名进行区分了
```bash
#停止rabbitmq节点服务
[root@rabbitmq01 ~]# rabbitmqctl stop_app
Stopping node rabbit@rabbitmq01 ...
#重置rabbitmq节点
[root@rabbitmq01 ~]# rabbitmqctl reset
Resetting node rabbit@rabbitmq01 ...
#启动rabbit节点服务
[root@rabbitmq01 ~]# rabbitmqctl start_app
Starting node rabbit@rabbitmq01 ...
###########以下操作 rabbitmq02、03都需执行###########
#停止rabbitmq节点服务
[root@rabbitmq02 ~]# rabbitmqctl stop_app
Stopping node rabbit@rabbitmq02 ...
#重置rabbitmq节点
[root@rabbitmq02 ~]# rabbitmqctl reset
Resetting node rabbit@rabbitmq02 ...
#以内存方式加入群集,后面是复制的rabbitmq01的节点名
[root@rabbitmq02 ~]# rabbitmqctl join_cluster --ram rabbit@rabbitmq01
Clustering node rabbit@rabbitmq02 with rabbit@rabbitmq01 ...
#启动rabbit节点服务
[root@rabbitmq02 ~]# rabbitmqctl start_app
Starting node rabbit@rabbitmq02 ...
#开启rabbitmq的web管理插件,以便可以通过浏览器进行访问
[root@rabbitmq02 ~]# rabbitmq-plugins enable rabbitmq_management
#######################查看群集状态#################################
[root@rabbitmq01 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq01 ...
[{nodes,[{disc,[rabbit@rabbitmq01]},
{ram,[rabbit@rabbitmq03,rabbit@rabbitmq02]}]},
{running_nodes,[rabbit@rabbitmq03,rabbit@rabbitmq02,rabbit@rabbitmq01]},
{cluster_name,<<"rabbit@rabbitmq01">>},
{partitions,[]},
{alarms,[{rabbit@rabbitmq03,[]},
{rabbit@rabbitmq02,[]},
{rabbit@rabbitmq01,[]}]}]
# rabbit01工作模式为磁盘节点;rabbit02和03为内存节点模式
# running_nodes:正在运行的节点
# cluster_name:节点名称
# alarms:发生问题时rabbit01、02、03会进行报警
#####由于刚才rabbitmq01重置,所以需要重新创建用户########
[root@rabbitmq01 ~]# rabbitmqctl add_user admin admin
Creating user "admin" ...
[root@rabbitmq01 ~]# rabbitmqctl set_user_tags admin administrator
Setting tags for user "admin" to [administrator] ...
```
## 访问web界面
群集内任意节点的IP+15672端口都可以进行登录访问




## 设置匹配策略


## 设置发布消息内容



# 单节点加入或退出群集
## 单节点加入集群
上面部署群集时,hosts文件已经可以解析群集内的节点,所以这里就省略解析了
```bash
#############在192.168.51.198服务器上操作###################
[root@rabbitmq04 ~]# yum -y localinstall erlang-18.1-1.el6.x86_64.rpm rabbitmq-server-3.6.6-1.el6.noarch.rpm socat-1.7.3.2-2.el7.x86_64.rpm
[root@rabbitmq04 ~]# chkconfig rabbitmq-server on
[root@rabbitmq04 ~]# systemctl start rabbitmq-server
[root@rabbitmq04 ~]# scp root@rabbitmq01:/var/lib/rabbitmq/.erlang.cookie /var/lib/rabbitmq/
#将群集中的cookie信息复制到本地,之后重启
[root@rabbitmq04 ~]# rabbitmqctl stop_app
[root@rabbitmq04 ~]# rabbitmqctl reset
[root@rabbitmq04 ~]# rabbitmqctl join_cluster --ram rabbit@rabbitmq01
#以内存运行的方式加入群集,若要以磁盘的方式加入,省略“--ram”选项即可
[root@rabbitmq04 ~]# rabbitmqctl start_app
#开启web管理页面
[root@rabbitmq04 ~]# rabbitmq-plugins enable rabbitmq_management
```
## 查看web界面

## 单节点退出集群
```bash
#先在rabbitmq04上面停止节点
[root@rabbitmq04 ~]# rabbitmqctl stop_app
#回到主节点(rabbitmq01)上删除节点
[root@rabbitmq01 ~]# rabbitmqctl -n rabbit@rabbitmq01 forget_cluster_node rabbit@rabbitmq04
#-n:指定节点名称
#forget_cluster_node:后面跟要删除的节点名称
```
## 查看web界面


Rabbitmq简介及部署群集