RabbitMQ有三种模式:单一模式,普通集群模式,镜像集群模式。
单一模式:即单机情况不做集群,就单独运行一个rabbitmq而已。
普通集群模式:普通集群模式下,不同的节点之间只会相互同步元数据(交换机、队列、绑定关系、Vhost的定义),而不会同步消息。默认情况下,消息队列位于一个节点上,指的节点就是master节点。
比如队列1的消息只存储在节点1上,节点2和节点3同步队列1的元数据,但是没有同步消息。生产者连接的是节点3,要将消息通过交换机A路由到队列1,最终消息还是会转发到节点1存储。同理,消费者连接节点2,要从队列1上拉取消息,消息会从节点1转发到节点2,其他节点起到一个路由的作用。
镜像模式:所谓镜像集群,可以真正做到保证消息百分之百不丢失,同时它还可以做到主节点在一某时刻失败它会自动的去做转换,自动的去做故障转移,保证系统的高可用。与普通集群模式不同的是,消息实体会主动在镜像节点间同步,而不是在客户端取数据时临时拉取。该模式带来的副作用也很明显,除了降低系统性能外,如果镜像队列数量过多,加之大量的消息进入,集群内部的网络带宽将会被这种同步通讯大大消耗掉。所以在对可靠性要求较高的场合中适用。
总结:普通集群模式与镜像集群模式的区别?
1、普通集群模式增加了RabbitMq系统的吞吐量,但不能实现系统的高可用,如果磁盘节点崩溃可能会导致数据丢失,不能再对队列、交换器、绑定关系、用户进行更改,更改权限、添加或删除集群节点也不能操作。
2、镜像集群模式是RabbitMq的HA部署方案,极大地提升 RabbitMQ 的可用性及可靠性,提供了数据冗余备份、避免单点故障的功能。但是镜像队列需要为每一个节点都要同步所有的消息实体,所以会导致网络带宽压力很大。 提供了数据的冗余备份,会导致存储压力变大,可能会出现IO瓶颈。具体怎样选择还需要使用者根据实际的业务场景选择合适的部署方案。
3、具体怎样选择还需要使用者根据实际的业务场景选择合适的部署方案。
RabbitMQ集群里有内存节点与磁盘节点之分。
内存节点(ram):就是将元数据都放在内存里,内存节点的话,只要服务重启,该节点的所有数据将会丢失。
硬盘节点(disc):就是将元数据都放在硬盘里,所以服务重启的话,数据也还是会存在的。
在RabbitMQ集群里,至少有一个磁盘节点,它用来持久保存元数据。新的节点加入集群后,会从磁盘节点上拷贝数据。但是,集群里也不必要每个节点都是磁盘节点,这主要是性能问题。例如,压力大的RPC服务,每秒都要创建和销毁数百个队列,如果集群里都是磁盘节点,意味着队列定义在每个节点上,都要写入磁盘才算成功,这样就会非常慢。
如果集群里只有一个磁盘节点,这个节点挂了,会发生什么?此时消息路由机制仍可正常进行(可以正常投递和消费消息),但是不能做如下事:
#create queues 创建队列
#create exchanges 创建交换器
#create bindings 创建绑定关系
#add users 创建用户
#change permissions 修改用户权限
#add or remove cluster nodes 新增或移除RabbitMQ集群节点
所以,如果考虑到高可用性,推荐在集群里保持2个磁盘节点,这样一个挂了,另一个还可正常工作。但上述最后一点,往集群里增加或删除节点,要求2个磁盘节点同时在线。如果考虑到高性能,推荐在集群里保持2个内存节点。
说明:持久化的消息,会同时存放在内存和磁盘。我们一般把应用连接到内存节点(读写快)。磁盘节点用来备份。
环境信息如下:
主机IP | 操作系统 | rabbitmq版本 | CPU架构 | 主机名 | 说明 |
---|---|---|---|---|---|
192.168.1.191 | Centos7.6 | 3.9.16 | x86_64 | rabbit01 | 磁盘节点 |
192.168.1.192 | Centos7.6 | 3.9.16 | x86_64 | rabbit02 | 内存节点 |
192.168.1.193 | Centos7.6 | 3.9.16 | x86_64 | rabbit03 | 内存节点 |
1、修改主机名和/etc/hosts文件
#1、设置主机名(主机192.168.1.191上执行)
[root@localhost ~]# hostnamectl set-hostname rabbit01
#2、设置主机名(主机192.168.1.192上执行)
[root@localhost ~]# hostnamectl set-hostname rabbit02
#3、设置主机名(主机192.168.1.193上执行)
[root@localhost ~]# hostnamectl set-hostname rabbit03
#4、修改hosts文件(主机192.168.1.191、192.168.1.192、192.168.1.193上执行)
[root@localhost ~]# vim /etc/hosts
192.168.1.191 rabbit01
192.168.1.192 rabbit02
192.168.1.193 rabbit03
2、关闭防护墙和selinux
#主机192.168.1.191、192.168.1.192、192.168.1.193上执行,需重启服务器
[root@localhost ~]# systemctl stop firewalld && systemctl disable firewalld
[root@localhost ~]# sed -i 's#enforcing#SELINUX=disabled#g' /etc/selinux/config
[root@localhost ~]# sed -i 's#enforcing#SELINUX=disabled#g' /etc/sysconfig/selinux
3、设置进程数
说明:root账号下ulimit -u出现的max user processes的值默认是/proc/sys/kernel/threads-max的值/2,即系统线程数的一半。普通账号下ulimit -u出现的max user processes的值默认是/etc/security/limits.d/20-nproc.conf文件中定义的大小。
#主机192.168.1.191、192.168.1.192、192.168.1.193上执行
#1.在/etc/security/limits.conf文件里添加如下内容
* soft nproc 65535
* hard nproc 65535
#注意:修改这里,普通用户max user process值是不生效的,需要修改/etc/security/limits.d/20-nproc.conf文件中的值。
4、设置文件描述符数
#主机192.168.1.191、192.168.1.192、192.168.1.193上执行
#1.在/etc/security/limits.conf文件里添加如下内容
* soft nofile 65535
* hard nofile 65535
说明:以下操作需分别在Rabbitmq镜像集群所有节点服务器上操作。
[root@rabbit01~]# curl -s https://packagecloud.io/install/repositories/rabbitmq/erlang/script.rpm.sh | sudo bash
[root@rabbit01~]# yum install erlang-23.3.4.11-1.el7.x86_64 -y
[root@rabbit01~]# yum install socat logrotate -y
说明:以下操作需分别在Rabbitmq镜像集群所有节点服务器上操作。
[root@rabbit01~]# wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.16/rabbitmq-server-3.9.16-1.el7.noarch.rpm
[root@rabbit01~]# yum install rabbitmq-server-3.9.16-1.el7.noarch.rpm -y
说明:默认配置在/etc/rabbitmq目录下,如果不存在直接创建就可以,RabbitMQ应用会自动加载;rabbitmq-env.conf包含重写RabbitMQ脚本和CLI工具中内置的默认值的环境变量。
#1、创建数据及日志目录
[root@rabbit01~]# mkdir /data/basic-data/rabbitmq-server/{data,logs} -pv
#2、修改rabbitmq-env.con文件
[root@rabbit01~]# vim /etc/rabbitmq/rabbitmq-env.conf
RABBITMQ_MNESIA_BASE=/data/basic-data/rabbitmq-server/data
RABBITMQ_LOG_BASE=/data/basic-data/rabbitmq-server/logs
#3、目录授权
[root@rabbit01~]# chown -R rabbitmq:rabbitmq /data/basic-data/rabbitmq-server -R
[root@rabbit01 ~]# vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.9.16/plugins/rabbit-3.9.16/ebin/rabbit.app
{vm_memory_high_watermark, 0.7},
说明:将rabbit01机器的.erlang.cookie文件复制到rabbit02和rabbit03机器(此文件在rabbitmq服务启动时自动生成),因为节点之间需要通过此文件来判断是否允许交流(判断是否属于集群内部节点),如果三台机器的此文件内容不一致则集群无法启动成功。此文件内容一般是由不超过255个数字或字母组成的字符串构成。
#1、启动rabbit01(192.168.1.191)节点的rabbitmq-server服务
[root@rabbit01 ~]# systemctl start rabbitmq-server
#2、将rabbit01机器的.erlang.cookie文件复制到rabbit02和rabbit03机器上
[root@rabbit01 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@rabbit02:/var/lib/rabbitmq/
[root@rabbit01 ~]# scp /var/lib/rabbitmq/.erlang.cookie root@rabbit03:/var/lib/rabbitmq/
#3、目录授权
[root@rabbit02 ~]# chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
[root@rabbit03 ~]# chown rabbitmq:rabbitmq /var/lib/rabbitmq/.erlang.cookie
#4、分别启动rabbit02节点(192.168.1.192)和rabbit03(192.168.1.193)节点的rabbitm-server服务
[root@rabbit02 ~]# systemctl start rabbitmq-server
[root@rabbit03 ~]# systemctl start rabbitmq-server
说明:分别在rabbit02节点和rabbit03节点上执行。
#1、停止服务
#注:这里的参数stop_app和stop是不一样的,stop是停掉服务,stop_app是停掉这个节点,但是并没有停止rabbitmq依赖的erlang进程
[root@rabbit02 ~]# rabbitmqctl stop_app
#2、加入集群,--ram是以内存方式加入
[root@rabbit02 ~]# rabbitmqctl join_cluster --ram rabbit@rabbit01
#3、启动服务
[root@rabbit02 ~]# rabbitmqctl start_app
说明:只需在任意一个节点上执行如下命令添加集群同步策略,这里默认操作在rabbit01节点。
# 所有队列exchangess 或者 queue都为镜像模式
# ^'表示所有匹配所有队列名称
[root@rabbit01 ~]# rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all"}" with priority "0" for vhost "/" ...
镜像模式参数
[root@rabbit01 ~]# rabbitmqctl set_policy [-p Vhost] Name Pattern Definition [Priority]
-p Vhost: 可选参数,针对指定vhost下的queue进行设置
Name: policy的名称
Pattern: exchanges或queue的匹配模式(正则表达式)
Definition:镜像定义,包括三个部分ha-mode, ha-params, ha-sync-mode
ha-mode:指明镜像队列的模式,有效值为 all/exactly/nodes
all:表示在集群中所有的节点上进行镜像
exactly:表示在指定个数的节点上进行镜像,节点的个数由ha-params指定
nodes:表示在指定的节点上进行镜像,节点名称通过ha-params指定
ha-params:ha-mode模式需要用到的参数
ha-sync-mode:进行队列中消息的同步方式,有效值为automatic和manual。
automatic:新增加节点自动同步全量数据。manual: 新增节点只同步新增数据,全量数据需要手工同步。
Priority:可选参数,policy的优先级
说明:以下操作只需在其中一个节点上操作即可,这里就在rabbit01节点上执行创建账号密码以及设置权限等操作。
# 1、创建用户并设置密码
[root@rabbit01 ~]# rabbitmqctl add_user admin admin123
#2、赋予其administrator角色
[root@rabbit01 ~]# rabbitmqctl set_user_tags admin administrator
#3、设置权限
[root@rabbit01 ~]# rabbitmqctl set_permissions -p "/" admin '.*' '.*' '.*'
说明:以下操作需分别在Rabbitmq镜像集群所有节点服务器上操作。
[root@rabbit01 ~]# rabbitmq-plugins enable rabbitmq_management
更多详细内容请参考:《Linux运维篇:Linux系统运维指南》