Ubuntu 一站式部署 RabbitMQ 4 并“彻底”迁移数据目录的终极实践
1 安装前准备
sudo apt update -y
sudo apt install -y curl gnupg apt-transport-https lsb-release jq
若计划将数据放到新磁盘(如 /dev/nvme0n1p1):
sudo mkfs.xfs /dev/nvme0n1p1
sudo mkdir /data
echo '/dev/nvme0n1p1 /data xfs defaults 0 0' | sudo tee -a /etc/fstab
sudo mount -a
2 官方仓库 + Erlang + RabbitMQ
Team RabbitMQ 在 Cloudsmith 维护滚动更新仓库,可同步 Erlang 子包。
## 2.1 导入 3 把签名钥匙
curl -1sLf "https://keys.openpgp.org/vks/v1/by-fingerprint/0A9AF2115F4687BD29803A206B73A36E6026DFCA" \| sudo gpg --dearmor -o /usr/share/keyrings/com.rabbitmq.team.gpg
curl -1sLf https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-erlang.E495BB49CC4BBE5B.key \| sudo gpg --dearmor -o /usr/share/keyrings/rabbitmq.erlang.gpg
curl -1sLf https://github.com/rabbitmq/signing-keys/releases/download/3.0/cloudsmith.rabbitmq-server.9F4587F226208342.key \| sudo gpg --dearmor -o /usr/share/keyrings/rabbitmq.server.gpg## 2.2 写入仓库列表
DIST=$(lsb_release -cs) # focal / jammy / noble
sudo tee /etc/apt/sources.list.d/rabbitmq.list <<EOF
# Erlang
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.erlang.gpg] \https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu $DIST main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.erlang.gpg] \https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-erlang/deb/ubuntu $DIST main
# RabbitMQ
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.server.gpg] \https://ppa1.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu $DIST main
deb [arch=amd64 signed-by=/usr/share/keyrings/rabbitmq.server.gpg] \https://ppa2.rabbitmq.com/rabbitmq/rabbitmq-server/deb/ubuntu $DIST main
EOF## 2.3 安装
sudo apt update -y
sudo apt install -y erlang-base erlang-asn1 erlang-crypto erlang-eldap \erlang-inets erlang-mnesia erlang-os-mon erlang-parsetools \erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssl \erlang-syntax-tools erlang-tools erlang-xmerl
# 默认 latest;若固定 3.13.7:
# sudo apt install -y rabbitmq-server=3.13.7-1
sudo apt install -y rabbitmq-server
服务安装即启动,systemd 单元 rabbitmq-server.service
已开机自启。
3 功能验收 & Web UI
sudo rabbitmq-plugins enable rabbitmq_management
sudo rabbitmq-diagnostics check_running
浏览 http://<host>:15672
(默认 guest/guest 仅限回环)。正式环境先建管理员并删除 guest:
sudo rabbitmqctl add_user admin 'Str0ngP@ss!'
sudo rabbitmqctl set_user_tags admin administrator
sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
sudo rabbitmqctl delete_user guest
4 数据-日志目录迁移:全量细节
4.1 为什么、迁去哪、用哪种环境变量?
变量 | 作用 | 场景 |
---|---|---|
RABBITMQ_MNESIA_BASE | 仅迁移 Mnesia(持久化消息 & 元数据) | 根分区容量紧张,日志放默认 /var/log |
RABBITMQ_LOG_BASE | 迁移日志文件 | 同上 |
RABBITMQ_BASE | 把 整个 RabbitMQ 运行目录(mnesia / log / plugins / pid 等)迁到同一路径 | 云主机挂整块数据盘、一劳永逸 |
systemd Environment= 覆写 | 不想写 rabbitmq-env.conf,单独管理每节点 | Kubernetes/Ansible 场景 |
官方《File and Directory Locations》详细说明了变量优先级:
systemd Environment > rabbitmq-env.conf > /etc/default > 内置默认
。
本文以 RABBITMQ_MNESIA_BASE + RABBITMQ_LOG_BASE 为例,演示单节点迁移;稍后补充 RABBITMQ_BASE
一键迁移脚本。
4.2 单节点迁移全流程(含验证 & 回滚)
# 1) 准备目录
sudo mkdir -p /data/rabbitmq/{mnesia,log}
sudo chown -R rabbitmq:rabbitmq /data/rabbitmq
sudo chmod 750 /data/rabbitmq# 2) 停节点并热备
sudo systemctl stop rabbitmq-server
sudo rsync -aH --progress /var/lib/rabbitmq/mnesia/ /data/rabbitmq/mnesia/
sudo rsync -aH --progress /var/log/rabbitmq/ /data/rabbitmq/log/# 3) 写 rabbitmq-env.conf
sudo tee /etc/rabbitmq/rabbitmq-env.conf <<'EOF'
RABBITMQ_MNESIA_BASE=/data/rabbitmq/mnesia
RABBITMQ_LOG_BASE=/data/rabbitmq/log
EOF# 4) 启动 & 验证
sudo systemctl start rabbitmq-server
sudo rabbitmq-diagnostics -q check_running
sudo rabbitmqctl status | grep -A3 "Directory"
# ≥4.1 输出示例
# "Data directory" => "/data/rabbitmq/mnesia",
# "Log file(s)" => "/data/rabbitmq/log/rabbit@host.log",
自动回滚脚本
#/usr/local/bin/rabbitmq-rollback.sh
sudo systemctl stop rabbitmq-server
sudo sed -i '/^RABBITMQ_MNESIA_BASE/d;/^RABBITMQ_LOG_BASE/d' /etc/rabbitmq/rabbitmq-env.conf
sudo systemctl start rabbitmq-server
echo "Rollback OK"
TIPS
- rsync 后不立即删除旧目录,观察 24 h 无异常再清理。
- AppArmor/SELinux 默认允许新路径,若自定义 profile 需加规则。
- 如果要完全迁走,省事做法:
mkdir /data/rmq && chown rabbitmq:rabbitmq /data/rmq echo 'RABBITMQ_BASE=/data/rmq' | sudo tee /etc/rabbitmq/rabbitmq-env.conf rsync -aH /var/lib/rabbitmq/ /data/rmq
4.3 集群滚动迁移方案
- 顺序停机:确保至少一半以上 Disc 节点在线。
- 迁移节点 A → 启动 →
rabbitmq-diagnostics cluster_status
正常后再迁移下一节点。 - 迁移期间,客户端采用 至少两台 Broker 的连接串,避免全部指向同一节点。
- 查看每次启动的 Feature Flags 与 Cookie 是否一致:
rabbitmq-diagnostics -q feature_flags_enabled stat ~/.erlang.cookie
- 完成后在任意节点执行
rabbitmqctl rotate_feature_flags_file
,保证文件路径随RABBITMQ_BASE
同步(4.x 新功能)。
4.4 在 IaC / systemd 中覆写
sudo systemctl edit rabbitmq-server
# 写入
[Service]
Environment="RABBITMQ_MNESIA_BASE=/data/rabbitmq/mnesia"
Environment="RABBITMQ_LOG_BASE=/data/rabbitmq/log"
# 保存退出
sudo systemctl daemon-reload
sudo systemctl restart rabbitmq-server
优点:不改任何包文件,易于 Ansible / SaltStack 模块化。
5 常见故障定位表
现象 | 原因 | 一键诊断 |
---|---|---|
permission denied open /data/... | 目录权限 / SELinux | ls -ld /data/rabbitmq; getenforce |
duplicate node name detected | hostname 冲突或 Cookie 改变 | hostnamectl + cat ~/.erlang.cookie |
Waiting for Mnesia tables 长时间卡住 | rsync 未包含硬链接 / inode 改变 | rabbitmq-diagnostics -q check_local_alarms 查看 disk_free 告警 |
systemd 环境变量无效 | 忘记 daemon-reload 或路径写错 | systemctl show -p Environment rabbitmq-server |
6 加固与运维进阶
- TLS / Mutual-TLS:在 5671/15671 端口启用证书 →
rabbitmq.conf
[listeners.ssl]
. - Prometheus:
rabbitmq_prometheus
插件已默认集成,新增-p 9419:9419
暴露/metrics
。 - Quorum Queues & Streams:4.x 默认开启,配合 SSD + RAID-10 可替代经典镜像队列。
- 自动化升级:配置
unattended-upgrades
仅对白名单包(erlang/ rabbitmq-server)放行,跨大版本前先rabbitmq-diagnostics upgrade_status
.
7.结语
本文以生产视角呈现 Ubuntu 上 RabbitMQ 4 的完整落地方案,重点打磨「数据-日志迁移」细枝末节,并兼顾单机、集群、IaC 三种场景。希望能让你在最短时间内完成 高可靠、路径清晰、可随时回滚 的企业级部署,尽享 4.x 带来的 Streams、高级监控、Quorum Queue 等特性。
有任何疑问,rabbitmq-diagnostics
+ 官方文档索引几乎可以解决 90% 难题,剩下 10% 抛给我,我们再一起深挖!