一、RabbitMQ简介
总结:RabbitMQ 3.13.7 最佳实践:优先使用 Quorum Queues,避免使用已弃用的镜像队列。
1.1、Classic Mirrored Queues(经典镜像队列)
Classic Mirrored Queues是RabbitMQ传统的高可用性解决方案,通过主动-被动复制模式在集群节点间同步队列数据。核心特性如下所示:
镜像复制:队列内容在多个节点间同步复制
自动故障转移:主节点故障时自动提升镜像节点为主节点
灵活配置:可通过策略(policy)精细控制复制行为
非强一致性:采用最终一致性模型
配置示例如下所示:
rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all"}'
1.2、Quorum Queues(仲裁队列)
Quorum Queues是RabbitMQ 3.8+引入的新型队列,基于Raft共识算法,提供更强的数据安全性和一致性保证。核心特性如下所示:
强一致性:基于Raft协议确保数据一致性
自动领导者选举:内置故障检测和领导者选举机制
简化运维:减少配置复杂性,提供更可靠的行为
现代架构:专为分布式系统设计
配置示例如下所示:
# 声明Quorum队列(客户端开发代码)
channel.queueDeclare("my-quorum-queue", true, false, false,
ImmutableMap.of("x-queue-type", "quorum"));
1.3、仲裁队列(Quorum Queues) vs 镜像队列(Classic Mirrored Queues) 核心区别
| 特性 | Classic Mirrored Queues(镜像队列) | Quorum Queues(仲裁队列) |
|---|---|---|
| 底层协议 | 基于 AMQP 0-9-1 + 自定义镜像同步 | 基于 Raft 共识算法 |
| 数据安全 | 可能丢失消息(网络分区时) | 消息安全,优先保证数据不丢失 |
| 复制机制 | 主从异步复制 | 基于Raft的共识复制 |
| 性能特点 | 较高吞吐,低延迟 | 稍低吞吐(因 Raft 日志同步) |
| 故障恢复 | 主从切换,可能丢失未同步消息 | 自动选举 Leader,无数据丢失 |
| 集群要求 | 至少 2 节点 | 至少 3 节点(奇数更佳) |
| 官方态度 | 已弃用(Deprecated),3.13+ 默认禁用 | 推荐使用,未来发展方向 |
| 资源使用 | 内存密集型 | 磁盘IO密集型 |
| 队列声明方式 | 通过策略(policy)启用镜像 | 声明时指定 x-queue-type=quorum |
1.4、集群角色介绍
针对 RabbitMQ 三节点集群的角色规划,我将为您提供几种经典且稳健的建议方案。核心原则是:确保高可用性和性能,避免单点故障。
在规划之前,请先理解 RabbitMQ 的两个核心概念:
1、磁盘节点:将元数据(队列、交换机、用户、权限、vhost 等)存储到磁盘。集群中必须至少有一个磁盘节点,否则所有变更(如创建队列)都会丢失。
2、内存节点:将元数据存储到内存中。性能更好,但节点重启或崩溃后会从磁盘节点同步数据。
方案一:经典稳健型(推荐)
这是最常用、最平衡的配置方案,适用于绝大多数生产环境。角色规划:2个磁盘节点 + 1个内存节点。
| 节点 | 节点类型 | 描述 |
|---|---|---|
| Node A | 磁盘节点 | 核心元数据存储节点,保证数据可靠性 |
| Node B | 磁盘节点 | 核心元数据存储节点,与 Node A 互为备份 |
| Node C | 内存节点 | 提供高性能的消息路由和消费,提升集群整体吞吐量 |
工作流程与优势:
1、元数据安全:两个磁盘节点相互冗余。即使一个磁盘节点(如 Node A)宕机,另一个磁盘节点(Node B)仍然能提供完整的元数据服务,集群可以继续运行(虽然此时不能再丢失唯一的磁盘节点)。
2、性能与资源平衡:内存节点(Node C)处理大部分的消息流入流出,因为它不需要进行磁盘 I/O 操作来访问元数据,速度更快。这减轻了两个磁盘节点的压力。
3、客户端连接:建议生产者连接到磁盘节点,消费者可以连接到任意节点,尤其是内存节点以获得最佳性能。使用负载均衡器将连接分发到三个节点是更好的做法。
4、队列镜像:这是实现消息本身高可用的关键,必须配置。建议设置策略,将所有队列镜像到所有节点(ha-mode: all)或至少两个节点。
此方案的优点:
高可用:元数据和消息(通过镜像)都有冗余。
性能佳:通过内存节点提升了吞吐量。
容错强:能容忍任意一个节点故障。
方案二:极致性能型
如果你的业务场景对消息吞吐量要求极高,且可以接受一定的元数据风险,可以考虑此方案。角色规划:1个磁盘节点 + 2个内存节点。
| 节点 | 节点类型 | 描述 |
|---|---|---|
| Node A | 磁盘节点 | 唯一的元数据权威来源 |
| Node B | 内存节点 | 高性能消息处理节点 |
| Node C | 内存节点 | 高性能消息处理节点 |
工作流程与优势:
1、性能最大化:三个节点中有两个是内存节点,整个集群的元数据操作速度会非常快。
2、单点故障风险:唯一的磁盘节点(Node A)是整个集群的“单点”。如果它宕机,会发生以下情况:集群虽然还能处理已存在的消息(因为消息存储在镜像队列中),但无法进行任何元数据变更(如创建新队列、新交换机、添加用户等)。如果此时最后一个磁盘节点无法恢复,你将面临元数据丢失的风险,需要通过备份来恢复。
3、注意事项:绝对不能让唯一的磁盘节点离线。如果需要维护,必须先优雅地关闭所有内存节点,最后关闭磁盘节点。启动时,必须先启动磁盘节点,再启动内存节点。
此方案的优点:
性能最高:最大限度地利用了内存节点的速度优势。
此方案的缺点:
元数据存在单点故障,风险较高。
方案三:极致可靠型
适用于对数据可靠性要求极端严格的金融、政务等场景,但对性能有一定牺牲。。角色规划:3个磁盘节点。
| 节点 | 节点类型 | 描述 |
|---|---|---|
| Node A | 磁盘节点 | 元数据存储节点 |
| Node B | 磁盘节点 | 元数据存储节点 |
| Node C | 磁盘节点 | 元数据存储节点 |
工作流程与优势:
1、最高可靠性:元数据在三节点上都有完整副本。即使两个节点同时宕机,最后一个节点仍然能保证元数据的完整性和集群的可用性(在仲裁方面,3节点集群允许1个节点故障)。
2、性能考虑:所有节点都需要进行磁盘 I/O 来维护元数据,因此元数据操作性能会低于包含内存节点的方案。但对于消息流本身,如果队列镜像配置得当,性能影响不大。
3、资源消耗:磁盘 I/O 和存储资源消耗会更高。
此方案的优点:
元数据可靠性最高,能容忍最多 (N-1)/2 个节点故障(对于3节点就是1个)。
此方案的缺点:
元数据操作性能相对较低。
对磁盘 I/O 和网络要求更高。
总结:三节点集群角色规划建议
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 2 磁盘 + 1 内存 | 绝大多数生产环境 | 可靠性、性能、资源消耗的最佳平衡 | 无显著缺点 |
| 1 磁盘 + 2 内存 | 极高吞吐量,可接受元数据风险 | 性能最优 | 元数据有单点故障风险 |
| 3 磁盘 | 极端数据可靠性要求 | 元数据可靠性最高 | 性能较低,资源消耗大 |
总结:直接选择【方案一:2个磁盘节点 + 1个内存节点】。这是一个经过大量实践验证的黄金配置。
1.5、RabbitMQ集群关键端口说明(含 TLS)
| 端口号 | 主要用途 | 是否需要对客户端开放 | 集群内要求 |
|---|---|---|---|
| 25672 | 节点间内部通信、集群数据和状态同步 | 通常不建议 | 必须一致 |
| 4369 | Erlang端口映射守护进程(epmd),用于节点发现 | 否 | 一致(默认) |
| 5672 | AMQP协议端口,供客户端连接和消息传递 | 是 | 可不同(若节点配置不同) |
| 15672 | HTTP API和管理控制台端口 | 是(如需使用控制台) | 可不同(若节点配置不同) |
如下图所示:
二、系统环境初始化
1、主机信息规划
| 主机IP | 主机名 | 操作系统 | CPU架构 | 说明 |
|---|---|---|---|---|
| 192.168.0.61 | mq1 | Ubuntu 22.04.5 LTS (Jammy Jellyfish) | x86_64 | 磁盘节点 |
| 192.168.0.62 | mq2 | Ubuntu 22.04.5 LTS (Jammy Jellyfish) | x86_64 | 磁盘节点 |
| 192.168.0.63 | mq3 | Ubuntu 22.04.5 LTS (Jammy Jellyfish) | x86_64 | 内存节点 |
2、配置主机名与解析
#1、设置主机名(主机192.168.0.61上执行)
root@localhost:~# hostnamectl set-hostname mq1 && bash
#2、设置主机名(主机192.168.0.62上执行)
root@localhost:~# hostnamectl set-hostname mq2 && bash
#3、设置主机名(主机192.168.0.63上执行)
root@localhost:~# hostnamectl set-hostname mq3 && bash
#4、修改hosts文件(主机192.168.0.61、192.168.0.62、192.168.0.63上执行)
vim /etc/hosts
cat >> /etc/hosts <<EOF
192.168.0.61 mq1
192.168.0.62 mq2
192.168.0.63 mq3
EOF
2、关闭防护墙和swap
说明:以下操作在rabbitmq集群所有节点均需执行。
systemctl stop ufw && systemctl disable ufw && ufw disable && swapoff -a
3、设置进程数和文件描述符数
说明:以下操作在rabbitmq集群所有节点均需执行。
vim /etc/security/limits.conf
rabbitmq soft nofile 65535
rabbitmq hard nofile 65535
rabbitmq soft nproc 65535
rabbitmq hard nproc 65535
4、创建运行用户
说明:以下操作在rabbitmq集群所有节点均需执行。
groupadd --gid 1305 rabbitmq
useradd -u 1305 -g 1305 -d /home/rabbitmq -s /bin/bash -m rabbitmq
passwd rabbitmq
三、安装Erlang软件
说明:RabbitMQ依赖于Erlang,需要先安装Erlang。查看官网对应的rabbitmq各个版本对应erlang的版本,如下图所示:
说明:以下操作在Rabbitmq集群所有节点均需执行。
1、安装必备依赖项
apt-get update -y
apt-get install curl gnupg -y
2、添加存储库签名密钥
curl -1sLf "https://keyserver.ubuntu.***/pks/lookup?op=get&search=0xf77f1eda57ebb1***" | gpg --dearmor | tee /usr/share/keyrings/***.launchpad.ppa.rabbitmq.erlang.gpg > /dev/null
3、启用apt的HTTPS传输方式
apt-get install apt-transport-https -y
4、添加源列表文件
add-apt-repository ppa:rabbitmq/rabbitmq-erlang-26
apt-get update -y
5、安装Erlang软件包
apt-get install -y erlang-base \
erlang-asn1 erlang-crypto erlang-eldap erlang-ftp erlang-i***s \
erlang-mnesia erlang-os-mon erlang-parsetools erlang-public-key \
erlang-runtime-tools erlang-snmp erlang-ssl \
erlang-syntax-tools erlang-tftp erlang-tools erlang-xmerl
6、查看erlang版本
root@mq1:~# erl
Erlang/OTP 26 [erts-14.2.5.11] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]
Eshell V14.2.5.11 (press Ctrl+G to abort, type help(). for help)
四、安装RabbitMQ软件
4.1、安装二进制包
说明:以下操作需分别在Rabbitmq集群所有节点服务器上操作。
root@mq1:~# cd /opt
root@mq1:/opt# wget https://github.***/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-generic-unix-3.13.7.tar.xz
root@mq1:/opt# tar axf rabbitmq-server-generic-unix-3.13.7.tar.xz
root@mq1:/opt# mv rabbitmq_server-3.13.7 rabbitmq
4.2、创建相关目录
说明:以下操作需分别在Rabbitmq集群所有节点服务器上操作。
# 创建数据目录
root@mq1:/opt/rabbitmq# mkdir /opt/rabbitmq/data
# 创建日志目录
root@mq1:/opt/rabbitmq# mkdir /opt/rabbitmq/logs
# 创建证书目录
root@mq1:/opt/rabbitmq# mkdir /opt/rabbitmq/ssl