RabbitMQ 原理与安装
参考:RabbitMQ 对 Erlang 版本要求, erlang下载页, rabbitmq下载页,延时队列插件-rabbitmq-delayed
RabbitMQ 是基于 AMQP(高级消息队列协议) 实现的开源消息中间件,由 Erlang 语言开发,核心优势是高可用、可扩展、支持多种消息模式,广泛用于系统解耦、异步通信、流量削峰等场景。
一、原理
-
角色与架构
RabbitMQ 的核心架构包含以下组件,通过 生产者 - 消费者 模型实现消息的可靠传递:
组件 作用 生产者(Producer) 发送消息的应用程序,将消息投递到 Exchange。 消费者(Consumer) 接收消息的应用程序,从 Queue 中获取并处理消息。 交换机(Exchange) 接收生产者的消息,根据绑定规则(Binding)将消息路由到对应的 Queue。 队列(Queue) 存储消息的容器,消息最终落地到 Queue,供消费者消费。 绑定(Binding) 连接 Exchange 和 Queue 的规则,包含路由键(Routing Key)匹配逻辑。 虚拟主机(VHost) 逻辑隔离的独立环境,可理解为 "命名空间",不同 VHost 互不干扰,支持权限隔离。 连接(Connection) 生产者 / 消费者与 RabbitMQ 服务器的 TCP 连接(长连接)。 信道(Channel) 建立在 Connection 之上的轻量级连接,避免频繁创建 TCP 连接,节省资源。 -
工作流程
-
生产者通过 Channel 向 RabbitMQ 服务器发送消息,指定目标 Exchange 和 Routing Key;
-
Exchange 根据自身类型和 Binding 规则,将消息路由到一个或多个 Queue;
-
消费者通过 Channel 监听指定的 Queue,获取并处理消息;
-
消息处理完成后,消费者向 RabbitMQ 发送 ACK(确认),RabbitMQ 才会删除该消息(可配置自动 / 手动 ACK)。

-
-
交换机(Exchange)类型
Exchange 是路由消息的核心,不同类型对应不同的路由规则:
类型 路由规则 典型场景 Direct 消息的 Routing Key 与 Binding 的 Routing Key 完全匹配,才路由到对应 Queue 一对一消息(精准路由) Fanout 忽略 Routing Key,将消息广播到所有绑定的 Queue 广播 / 订阅(如日志推送) Topic 支持通配符匹配( *匹配一个单词,#匹配多个单词),模糊路由多对多消息(如按主题分类) Headers 不依赖 Routing Key,通过消息头(Headers)键值对匹配 复杂属性匹配(较少用) -
核心特性
- 消息确认机制:生产者确认(Publisher Confirm)确保消息到达 Exchange;消费者 ACK 确保消息被正确处理;
- 持久化:Queue、Exchange、消息均可配置持久化,避免服务器宕机丢失;
- 死信队列(DLX):处理失败 / 过期的消息,支持消息重试或归档;
- 延迟队列:通过死信队列 + TTL(消息过期时间)实现延迟消息;
- 集群与镜像队列:支持多节点集群,镜像队列保障 Queue 高可用;
- 限流:消费者可限制单次获取的消息数量,避免过载。
二、单机安装
-
前置说明
- RabbitMQ 依赖 Erlang 语言环境,需先安装 Erlang,再安装 RabbitMQ。
- 服务器已配置网络,关闭 / 放行防火墙(或开放 5672(AMQP)、15672(管理界面)端口);
- 系统版本:CentOS 7/8、Ubuntu 20.04+ 均可,以下以 CentOS 7 为例。
-
安装Erlang
-
通过 YUM 源安装
bash# 1. 添加 Erlang 官方 YUM 源 vim /etc/yum.repos.d/rabbitmq-erlang.repo # 写入以下内容(以 Erlang 25.3 为例) [rabbitmq-erlang] name=rabbitmq-erlang baseurl=https://packagecloud.io/rabbitmq/erlang/el/7/$basearch repo_gpgcheck=1 gpgcheck=1 enabled=1 gpgkey=https://packagecloud.io/rabbitmq/erlang/gpgkey https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt # 2. 安装 Erlang yum install -y erlang # 3. 验证 Erlang 安装 erl -v # 输出 Erlang 版本即成功 -
源码安装 <-- 推荐 扩展性更强
bash用web界面下载: https://www.erlang.org/patches/otp-26.2.5.16 yum -y install gcc gcc-c++ ncurses-devel wxGTK wxGTK-devel gtk2-devel libGLU-devel openssl openssl-devel cd /opt/ tar xf otp_src_26.2.5.16.tar.gz cd /opt/otp_src_26.2.5.16 ./configure --prefix=/opt/mq/erlang make -j 4 && make -j 4 install # 验证版本 /opt/mq/erlang/bin/erl Erlang/OTP 26 [erts-14.2.5.12] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
-
-
安装 RabbitMQ
-
yum安装
bash# 1. 添加 RabbitMQ YUM 源 vim /etc/yum.repos.d/rabbitmq.repo # 写入以下内容(以 RabbitMQ 3.12.x 为例) [rabbitmq_server] name=rabbitmq_server baseurl=https://packagecloud.io/rabbitmq/rabbitmq-server/el/7/$basearch repo_gpgcheck=1 gpgcheck=1 enabled=1 gpgkey=https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt # 2. 安装 RabbitMQ 服务器 yum install -y rabbitmq-server # 3. 验证安装 rabbitmq-server -v # 输出 RabbitMQ 版本即成功 -
源码安装
bash# 下载包 wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.13.7/rabbitmq-server-generic-unix-3.13.7.tar.xz # 解压并配置 tar xf rabbitmq-server-generic-unix-3.13.7.tar.xz -C /opt/mq/ cd /opt/mq/ mv rabbitmq_server-3.13.7/ rabbitmq chmod 777 rabbitmq/ -R cd rabbitmq mkdir license mv LICENSE* license <-- 把源码包里的LICENSE文件都挪走 # 创建数据/日志目录并授权 mkdir -p /opt/mq/rabbitmq/{mnesia,log} chmod -R 755 /opt/mq/rabbitmq/{mnesia,log}-
配置自启脚本
bashcat > /etc/systemd/system/rabbitmq-server.service << EOF [Unit] Description=RabbitMQ Server Documentation=man:rabbitmq-server(8) After=network.target Wants=network.target [Service] User=root Group=root Environment="PATH=/opt/mq/erlang/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" Environment="RABBITMQ_HOME=/opt/mq/rabbitmq" Environment="RABBITMQ_MNESIA_BASE=/opt/mq/rabbitmq/mnesia" Environment="RABBITMQ_LOG_BASE=/opt/mq/rabbitmq/log" ExecStart=/opt/mq/rabbitmq/sbin/rabbitmq-server ExecStop=/opt/mq/rabbitmq/sbin/rabbitmqctl stop ExecStop=/bin/sh -c 'PID=$(rabbitmqctl status 2>/dev/null | grep "pid" | awk "{print \$2}" | tr -d ","); [ -n "$PID" ] && kill -9 $PID' ExecReload=/opt/mq/rabbitmq/sbin/rabbitmqctl stop && /opt/mq/rabbitmq/sbin/rabbitmq-server Restart=on-failure RestartSec=5 TimeoutStartSec=60 TimeoutStopSec=60 LimitNOFILE=65535 # 提高文件描述符限制(生产环境必备) LimitNPROC=65535 PrivateTmp=true [Install] WantedBy=multi-user.target EOF -
启动服务
bash# 启动 RabbitMQ systemctl start rabbitmq-server # 设置开机自启 systemctl enable rabbitmq-server # 查看状态(active (running) 即为正常) systemctl status rabbitmq-server
-
-
2.1、启用管理插件
-
RabbitMQ 默认无 Web 界面,需手动启用插件:
bash# 配置环境变量 echo "RABBITMQ_HOME=/opt/mq/erlang" >> /etc/profile echo "export PATH=\$RABBITMQ_HOME/bin:\$PATH" >> /etc/profile source /etc/profile cd /opt/mq/rabbitmq/sbin # 启用管理插件 [root@localhost sbin]# ./rabbitmq-plugins enable rabbitmq_management ..... Applying plugin configuration to rabbit@localhost... The following plugins have been enabled: rabbitmq_management rabbitmq_management_agent rabbitmq_web_dispatch started 3 plugins. # 重启服务(可选) systemctl restart rabbitmq-server -
添加用户
bashcd /opt/mq/rabbitmq/sbin # 1. 添加管理员用户(替换 username/password 为自定义) ./rabbitmqctl add_user admin 123456 # 2. 设置用户为管理员角色 ./rabbitmqctl set_user_tags admin administrator # 3. 设置用户权限(允许访问所有 VHost,读写所有资源) ./rabbitmqctl set_permissions -p / admin ".*" ".*" ".*" # 4. 可选:删除默认 guest 用户(提高安全性) ./rabbitmqctl delete_user guest # 5. 查看用户列表 ./rabbitmqctl list_users -
开放端口(防火墙)- 如开
bash# 开放 AMQP 端口(5672)和 Web 管理端口(15672) firewall-cmd --add-port=5672/tcp --permanent firewall-cmd --add-port=15672/tcp --permanent # 重启防火墙 firewall-cmd --reload -
访问 Web 管理界面
打开浏览器,访问
http://服务器IP:15672,输入上述创建的用户名(如 admin)和密码(如 123456),即可进入 RabbitMQ 管理控制台:- 可查看 Queue、Exchange、用户、连接等信息;
- 可手动创建 Queue/Exchange、绑定规则、发送测试消息等。
三、集群安装
RabbitMQ 集群核心是 Erlang 分布式节点通信 + 队列镜像 / 分片 ,实现高可用和负载均衡。以下以 3 节点集群 为例(CentOS 7/8,自定义路径 /opt/mq/rabbitmq、/opt/mq/erlang),覆盖集群搭建、镜像队列配置、故障切换全流程。
-
前置说明
-
基础环境准备
节点 IP 主机名(建议) 核心路径 节点 1(主) 192.168.189.128 rabbitmq-node1 /opt/mq/rabbitmq、/opt/mq/erlang 节点 2 192.168.189.129 rabbitmq-node2 同上 节点 3 192.168.189.135 rabbitmq-node3 同上 -
统一主机名与 hosts 解析
bash# 1. 设置主机名(每个节点对应自己的主机名) # 节点1: hostnamectl set-hostname rabbitmq-node1 # 节点2: hostnamectl set-hostname rabbitmq-node2 # 节点3: hostnamectl set-hostname rabbitmq-node3 # 2. 修改 /etc/hosts,添加所有节点解析 cat >> /etc/hosts << EOF 192.168.1.10 rabbitmq-node1 192.168.1.11 rabbitmq-node2 192.168.1.12 rabbitmq-node3 EOF # 3. 验证解析 ping rabbitmq-node2 -c 2 # 节点1 ping 节点2,能通即正常 -
端口说明
端口号 核心角色 通信对象 开放范围建议 关键作用概括 4369 Erlang 节点发现 集群内所有节点互访 仅集群内网 节点发现,Erlang 分布式基础 25672 集群内部通信 集群内所有节点互访 仅集群内网 同步元数据、镜像队列数据复制 5672 客户端业务通信 生产者 / 消费者 ↔ 集群 仅业务网段 AMQP 协议端口,承载消息收发 15672 Web 管理界面 运维端 ↔ 集群 仅运维网段 可视化管理、监控集群状态 -
依赖逻辑:
4369(节点发现)→ 25672(集群通信)→ 5672(业务交互)→ 15672(运维管理)- 无 4369:集群节点无法发现彼此,集群搭建失败;
- 无 25672:节点可发现但无法同步数据,集群退化为独立节点;
- 无 5672:客户端无法收发消息,业务中断;
- 无 15672:仅影响可视化管理,不影响集群核心功能。
-
防火墙配置
bash# 临时关闭防火墙(测试环境) systemctl stop firewalld && systemctl disable firewalld # 生产环境开放端口(替代关闭防火墙) firewall-cmd --add-port=4369/tcp --permanent firewall-cmd --add-port=25672/tcp --permanent firewall-cmd --add-port=5672/tcp --permanent firewall-cmd --add-port=15672/tcp --permanent firewall-cmd --reload # 富策略 firewall-cmd --add-rich-rule='rule family="ipv4" source address="地址/32" port port="端口" protocol="tcp" accept' --permanent firewall-cmd --reload
-
-
统一 Erlang Cookie
RabbitMQ 集群通过 Erlang Cookie 认证节点,所有节点必须使用相同的 Cookie 文件:
bash# 1. 先停止所有节点的 RabbitMQ 服务 systemctl stop rabbitmq-server # 2. 从节点1复制 Cookie 到其他节点(推荐以节点1为基准) # 节点1 执行(查看 Cookie 路径,默认在 /root/.erlang.cookie): cat /root/.erlang.cookie # 从节点1 scp 到 节点2、3 scp /root/.erlang.cookie root@rabbitmq-node2:/root/ scp /root/.erlang.cookie root@rabbitmq-node3:/root/ # 3. 统一 Cookie 权限(所有节点) chmod 400 /root/.erlang.cookie # 必须 400 权限,否则认证失败
-
-
从节点1将 erlang、rabbitmq 压缩直接scp到 节点2、3
- 节点2、3 跟单机一样都配一遍
3.1、初始化集群
-
启动所有节点的 RabbitMQ 服务
bash# 启动服务 systemctl start rabbitmq-server # 验证启动状态 systemctl status rabbitmq-server # 确保 active (running) -
将节点 2、3 加入节点 1 的集群
bash# 1. 停止节点 2.3 的 RabbitMQ 应用(保留 Erlang 节点运行) /opt/mq/rabbitmq/sbin/rabbitmqctl stop_app # 2. 重置节点(清空本地数据,避免冲突) /opt/mq/rabbitmq/sbin/rabbitmqctl reset # 3. 加入节点 1 的集群(指定节点 1 的 Erlang 节点名,格式:rabbit@主机名) /opt/mq/rabbitmq/sbin/rabbitmqctl join_cluster rabbit@rabbitmq-node1 # 4. 重启 RabbitMQ 应用 /opt/mq/rabbitmq/sbin/rabbitmqctl start_app # 5. 验证集群状态 /opt/mq/rabbitmq/sbin/rabbitmqctl cluster_status Running Nodes rabbit@rabbitmq-node1 rabbit@rabbitmq-node2 rabbit@rabbitmq-node3
3.2、配置镜像队列
默认集群中,Queue 仅存储在创建它的节点上,若该节点宕机,Queue 不可用。镜像队列 会将 Queue 复制到集群多个节点,实现故障自动切换。
-
设置镜像队列策略(所有节点生效)
bash# 在任意节点执行(推荐节点1) /opt/mq/rabbitmq/sbin/rabbitmqctl set_policy ha-all "^" '{"ha-mode":"all","ha-sync-mode":"automatic"}' # 参数说明: # ha-all:策略名称(自定义) # "^":匹配所有队列(正则,也可指定特定队列,如 "^order.*" 匹配以 order 开头的队列) # ha-mode":"all":将队列镜像到集群所有节点(可选 "exactly" 配置固定数量,如 "ha-params":2 镜像到2个节点) # ha-sync-mode":"automatic":自动同步队列数据(默认手动,需手动执行 sync_queue) # 返回值 Setting policy "ha-all" for pattern "^" to "{"ha-mode":"all","ha-sync-mode":"automatic"}" with priority "0" for vhost "/" ... -
验证镜像队列策略
bash[root@localhost mq]# /opt/mq/rabbitmq/sbin/rabbitmqctl list_policies Listing policies for vhost "/" ... vhost name pattern apply-to definition priority / ha-all ^ all {"ha-mode":"all","ha-sync-mode":"automatic"} 0
3.3、集群管理与常用操作
-
查看集群状态
bash/opt/mq/rabbitmq/sbin/rabbitmqctl cluster_status # 关键输出: # - nodes.disc:磁盘节点列表(所有节点默认是磁盘节点) # - running_nodes:运行中的节点 # - partitions:网络分区(空则正常) Maintenance status Node: rabbit@rabbitmq-node1, status: not under maintenance关键信息 含义与影响 状态值:not under maintenance 节点正常对外提供服务,可接收客户端连接(生产者 / 消费者)、参与集群通信(元数据同步、镜像队列复制),无功能限制。 适用场景 集群日常运行状态,所有节点均在线且正常工作,无需人工干预。 -
移除集群节点(如移除节点 3)
bash# 1. 节点3 执行:停止应用并重置 /opt/mq/rabbitmq/sbin/rabbitmqctl stop_app /opt/mq/rabbitmq/sbin/rabbitmqctl reset # 2. 节点1 执行:移除节点3 /opt/mq/rabbitmq/sbin/rabbitmqctl forget_cluster_node rabbit@rabbitmq-node3 # 3. 节点3 执行:重启应用(退出集群后独立运行) /opt/mq/rabbitmq/sbin/rabbitmqctl start_app -
故障切换测试
bash# 1. 停止节点1的 RabbitMQ 服务(模拟宕机) systemctl stop rabbitmq-server # 2. 节点2 查看集群状态(应显示节点1停止,节点2/3运行) /opt/mq/rabbitmq/sbin/rabbitmqctl cluster_status # 3. 验证队列可用性:生产者/消费者连接节点2,仍可正常收发消息 # 4. 重启节点1(自动重新加入集群) systemctl start rabbitmq-server -
集群用户同步
RabbitMQ 集群会自动同步用户、权限、VHost 配置,只需在一个节点创建用户,所有节点生效
bash# 在节点1创建管理员用户(所有节点可共用) /opt/mq/rabbitmq/sbin/rabbitmqctl add_user admin 123456 /opt/mq/rabbitmq/sbin/rabbitmqctl set_user_tags admin administrator /opt/mq/rabbitmq/sbin/rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
3.4、启用管理插件
访问任意节点的管理界面(http://节点IP:15672),登录 admin 用户:
-
顶部导航栏
Admin→Nodes:查看所有节点状态(运行 / 停止); -
Queues页面:队列旁会显示Mirrored to [2] nodes(镜像到 2 个节点),表示镜像队列生效; -
Admin→Policies:查看已配置的镜像队列策略。

四、注意事项
-
注意事项
-
磁盘节点 vs 内存节点
- 默认所有节点是 磁盘节点(存储集群元数据、队列数据),生产环境建议至少 2 个磁盘节点(避免单点故障);
- 内存节点(仅存储内存,速度快):加入集群时指定
--ram,如rabbitmqctl join_cluster --ram rabbit@rabbitmq-node1,适合高并发读场景。
-
网络分区处理
集群节点网络中断会导致 网络分区,需配置自动恢复:
bash# 所有节点修改 RabbitMQ 配置文件(/etc/rabbitmq/rabbitmq.conf) echo "cluster_partition_handling = autoheal" >> /etc/rabbitmq/rabbitmq.conf # 重启所有节点 systemctl restart rabbitmq-server -
Erlang 版本兼容
所有节点必须使用 相同版本的 Erlang 和 RabbitMQ,否则集群无法通信。
-
-
常见故障排查
-
节点加入集群失败
- 检查
/.erlang.cookie文件是否一致、权限是否为 400; - 检查 hosts 解析是否正确,节点间 4369/25672 端口是否通;
- 执行
rabbitmqctl status查看节点状态,确保 Erlang 节点正常运行。
- 检查
-
镜像队列不生效
-
检查策略是否匹配队列名称(正则是否正确);
-
新建队列才会应用策略,已有队列需重新创建或手动同步:
bashrabbitmqctl sync_queue 队列名
-
-
节点宕机后队列不可用
- 确认镜像队列策略已配置(
ha-mode:all); - 检查节点宕机后,其他节点是否在
running_nodes列表中。
- 确认镜像队列策略已配置(
-
-
生产环境优化建议
- 节点数量:建议 3/5 个节点(奇数,避免脑裂);
- 存储:队列数据目录挂载独立磁盘,开启持久化;
- 监控:通过 Prometheus + Grafana 监控集群节点状态、队列长度、消息速率;
- 限流 :配置消费者限流(
basic.qos),避免单节点过载; - 备份 :定期执行
rabbitmqctl export_definitions备份集群配置。