1 前言
RabbitMQ集群分为两种模式:
- 普通模式:创建好RabbitMQ之后的默认模式。
- 镜像模式:把需要的队列做成镜像队列。
普通集群模式
queue 创建之后,如果没有其它 policy,消息实体只存在于其中一个节点, A、 B 两个 Rabbitmq 节点仅有相同的元数据,即队列结构,但队列的数据仅保存有一份,即创建该队列的 rabbitmq 节点(A 节点),当消息进入 A 节点的 Queue 中后, consumer 从 B 节点拉取时, RabbitMQ 会临时在 A、 B 间进行消息传输,把 A 中的消息实体取出并经过 B 发送给 consumer,所以 consumer 可以连接每一个节点,从中取消息,该模式存在一个问题就是当 A 节点故障后,B节点无法取到 A 节点中还未消费的消息实体。
镜像集群模式
把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案(镜像模式是在普通模式的基础上,增加一些镜像策略)该模式解决了上述问题,其实质和普通模式不同之处在于,消息实体会主动在镜像节点间同步,而不是在consumer取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用,一个队列想做成镜像队列,需要先设置 policy,然后客户端创建队列的时候, rabbitmq 集群根据“队列名称”自动设置是普通集群模式或镜像队列。
RabbitMQ集群中有两种节点类型
- 内存节点:只将数据保存到内存。
- 磁盘节点:保存数据到内存和磁盘。
内存节点虽然不写入磁盘,但是它执行效率比磁盘节点要好,集群中,只需要一个磁盘节点来保存数据就足够了,如果集群中只有内存节点,那么,不能全部停止它们,否则所有数据消息在服务器全部停机之后都会丢失。
推荐使用方案
在一个 rabbitmq 集群里,有 3 台或以上机器,其中 1 台使用磁盘模式,其它节点使用内存模式,内存节点访问速度更快,由于磁盘 IO 相对较慢,因此可作为数据备份使用。
2 环境
IP | 主机名 | 角色 | rabbitmq版本 | erlang版本 |
---|---|---|---|---|
192.168.7.11 | rabbitmq-server1 | 内存节点 | 3.8.3 | 22.3.4 |
192.168.7.12 | rabbitmq-server2 | 内存节点 | 3.8.3 | 22.3.4 |
192.168.7.13 | rabbitmq-server3 | 磁盘节点 | 3.8.3 | 22.3.4 |
OS:CentOS7.4
firewalld和SELinux:禁用
erlang下载地址
rabbitmq下载地址
同步系统时间
3 安装部署
3.1 主机名解析设置
集群中的每台服务器都要同步
# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.7.11 rabbitmq-server1
192.168.7.12 rabbitmq-server2
192.168.7.13 rabbitmq-server3
3.2 各服务器安装RabbitMQ
这里分别演示通过下载指定版本的rpm包安装和通过编写.repo文件安装的两种方式
3.2.1 下载指定版本的rpm包安装
在安装rabbitmq之前,必须安装受支持的erlang版本,rabbitmq和erlang的版本兼容性要求参考这里
安装erlang
# wget https://dl.bintray.com/rabbitmq-erlang/rpm/erlang/22/el/7/x86_64/erlang-22.3.4-1.el7.x86_64.rpm
# yum -y install erlang-22.3.4-1.el7.x86_64.rpm
安装rabbitmq
# wget https://dl.bintray.com/rabbitmq/rpm/rabbitmq-server/v3.8.x/el/7/noarch/rabbitmq-server-3.8.3-1.el7.noarch.rpm
# yum -y install rabbitmq-server-3.8.3-1.el7.noarch.rpm
3.2.2 编写.repo文件安装
# cat rabbitmq.repo
[bintray-rabbitmq-server]
name=bintray-rabbitmq-rpm
baseurl=https://dl.bintray.com/rabbitmq/rpm/rabbitmq-server/v3.8.x/el/7
gpgcheck=1
gpgkey=https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc
enabled=1
[bintray-rabbitmq-erlang]
name=bintray-erlang-rpm
baseurl=https://dl.bintray.com/rabbitmq-erlang/rpm/erlang/22/el/7
gpgcheck=1
gpgkey=https://dl.bintray.com/rabbitmq/Keys/rabbitmq-release-signing-key.asc
enabled=1
# yum -y install erlang rabbitmq-server
3.3 启动RabbitMQ服务并设置为开机启动
# systemctl enable --now rabbitmq-server
3.4 创建RabbitMQ集群
Rabbitmq 的集群是依赖于 erlang 的集群来工作的,所以必须先构建起 erlang 的集群环境,而 Erlang 的集群中各节点是通过一个 magic cookie 来实现的,这个cookie 存放在 /var/lib/rabbitmq/.erlang.cookie 中,文件是 400 的权限,所以必须保证各节点 cookie 保持一致,否则节点之间就无法通信。
3.4.1 各服务器同步cookie文件
各服务器先关闭rabbitmq服务
# systemctl stop rabbitmq-server
在rabbitmq-server1向其它两个服务器同步cookie文件
# for i in 12 13 ; do scp /var/lib/rabbitmq/.erlang.cookie 192.168.7.$i:/var/lib/rabbitmq/ ; done
各服务器启动rabbitmq服务
# systemctl start rabbitmq-server
3.4.2 查看当前集群状态
[root@rabbitmq-server1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq-server1 ...
Basics
Cluster name: rabbit@rabbitmq-server1
Disk Nodes
rabbit@rabbitmq-server1
Running Nodes
rabbit@rabbitmq-server1
Versions
rabbit@rabbitmq-server1: RabbitMQ 3.8.3 on Erlang 22.3.4
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@rabbitmq-server1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq-server1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Feature flags
Flag: implicit_default_bindings, state: enabled
Flag: quorum_queue, state: enabled
Flag: virtual_host_metadata, state: enabled
[root@rabbitmq-server2 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq-server2 ...
Basics
Cluster name: rabbit@rabbitmq-server2
Disk Nodes
rabbit@rabbitmq-server2
Running Nodes
rabbit@rabbitmq-server2
Versions
rabbit@rabbitmq-server2: RabbitMQ 3.8.3 on Erlang 22.3.4
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@rabbitmq-server2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq-server2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Feature flags
Flag: implicit_default_bindings, state: enabled
Flag: quorum_queue, state: enabled
Flag: virtual_host_metadata, state: enabled
[root@rabbitmq-server3 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq-server3 ...
Basics
Cluster name: rabbit@rabbitmq-server3
Disk Nodes
rabbit@rabbitmq-server3
Running Nodes
rabbit@rabbitmq-server3
Versions
rabbit@rabbitmq-server3: RabbitMQ 3.8.3 on Erlang 22.3.4
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@rabbitmq-server3, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq-server3, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Feature flags
Flag: implicit_default_bindings, state: enabled
Flag: quorum_queue, state: enabled
Flag: virtual_host_metadata, state: enabled
3.4.3 创建RabbitMQ集群
3.4.3.1 在rabbitmq-server1作为内存节点连接起来,并作为内存节点,在rabbitmq-server1上执行以下命令
停止app服务
# rabbitmqctl stop_app
Stopping rabbit application on node rabbit@rabbitmq-server1 ...
清空元数据
# rabbitmqctl reset
Resetting node rabbit@rabbitmq-server1 ...
将 rabbitmq-server1 添加到集群当中,并成为内存节点,不加--ram 默认是磁盘节点
# rabbitmqctl join_cluster rabbit@rabbitmq-server3 --ram
Clustering node rabbit@rabbitmq-server1 with rabbit@rabbitmq-server3
启动app服务
# rabbitmqctl start_app
Starting node rabbit@rabbitmq-server1 ...
completed with 0 plugins.
3.4.3.2 在rabbitmq-server2作为内存节点连接起来,并作为内存节点,在rabbitmq-server2上执行以下命令
操作步骤同上
3.4.4 将集群设置为镜像模式
以下操作只需要在集群中的其中一台节点执行
# rabbitmqctl set_policy ha-all "#" '{"ha-mode":"all"}'
Setting policy "ha-all" for pattern "#" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...
3.4.5 验证当前集群状态
[root@rabbitmq-server1 ~]# rabbitmqctl cluster_status
Cluster status of node rabbit@rabbitmq-server1 ...
Basics
Cluster name: rabbit@rabbitmq-server3
Disk Nodes
rabbit@rabbitmq-server3
RAM Nodes
rabbit@rabbitmq-server1
rabbit@rabbitmq-server2
Running Nodes
rabbit@rabbitmq-server1
rabbit@rabbitmq-server2
rabbit@rabbitmq-server3
Versions
rabbit@rabbitmq-server1: RabbitMQ 3.8.3 on Erlang 22.3.4
rabbit@rabbitmq-server2: RabbitMQ 3.8.3 on Erlang 22.3.4
rabbit@rabbitmq-server3: RabbitMQ 3.8.3 on Erlang 22.3.4
Alarms
(none)
Network Partitions
(none)
Listeners
Node: rabbit@rabbitmq-server1, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq-server1, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbitmq-server2, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq-server2, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Node: rabbit@rabbitmq-server3, interface: [::], port: 25672, protocol: clustering, purpose: inter-node and CLI tool communication
Node: rabbit@rabbitmq-server3, interface: [::], port: 5672, protocol: amqp, purpose: AMQP 0-9-1 and AMQP 1.0
Feature flags
Flag: implicit_default_bindings, state: enabled
Flag: quorum_queue, state: enabled
Flag: virtual_host_metadata, state: enabled
4 web界面验证当前集群状态
4.1 各服务器启动web插件
# rabbitmq-plugins enable rabbitmq_management
启动web插件后会监听15672端口,该端口是web管理端口
# ss -nlt|grep 15672
LISTEN 0 128 *:15672 *:*
4.2 登录web管理界面
rabbitmq 从 3.3.0 开始禁止使用 guest/guest 权限通过除 localhost 外的访问,直
接访问报错如下:
允许方式,每个节点都操作
# vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.8.3/ebin/rabbit.app
39 {loopback_users, []}, #删除被禁止登陆的 guest 账户
# systemctl restart rabbitmq-server.service #重启 rabbitmq 服务
4.3 开启web插件后的集群状态
5 RabbitMQ常用命令
# 创建vhost
[root@rabbitmq-server1 ~]# rabbitmqctl add_vhost hechunping
Adding vhost "hechunping" ...
# 列出所有vhost
[root@rabbitmq-server1 ~]# rabbitmqctl list_vhosts
Listing vhosts ...
name
/
hechunping
# 列出所有队列
[root@rabbitmq-server1 ~]# rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
# 删除指定vhost
[root@rabbitmq-server1 ~]# rabbitmqctl delete_vhost hechunping
Deleting vhost "hechunping" ...
# 添加账户hechunping密码为123.com
[root@rabbitmq-server1 ~]# rabbitmqctl add_user hechunping 123.com
Adding user "hechunping" ...
# 更改用户hechunping密码
[root@rabbitmq-server1 ~]# rabbitmqctl change_password hechunping 123456
Changing password for user "hechunping" ...
# 设置 hechunping 用户对 hechunping 的 vhost 有读写权限,三个点分别表示配置正则、读和写
[root@rabbitmq-server1 ~]# rabbitmqctl set_permissions -p hechunping hechunping ".*" ".*" ".*"
Setting permissions for user "hechunping" in vhost "hechunping" ...