版本升级
安全地升级 RabbitMQ 版本是运维的重要工作,需要充分准备和测试。
🎯 本章目标
- 了解版本升级的注意事项
- 掌握单节点和集群升级流程
- 学会处理升级中的常见问题
📋 升级前准备
1. 版本兼容性检查
# 查看当前版本
rabbitmqctl status | grep -E "RabbitMQ|Erlang"
# 检查 Erlang 版本要求
# RabbitMQ 3.12 需要 Erlang 25.x 或 26.x
# RabbitMQ 4.x 需要 Erlang 26.x+
版本兼容性矩阵
| RabbitMQ | Erlang 最低 | Erlang 推荐 |
|---|---|---|
| 3.12.x | 25.0 | 26.x |
| 3.13.x | 26.0 | 26.x |
| 4.0.x | 26.2 | 26.x |
| 4.1.x | 26.2 | 26.x |
2. 备份数据
#!/bin/bash
# pre-upgrade-backup.sh
BACKUP_DIR="/backup/rabbitmq-upgrade-$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 导出定义
rabbitmqadmin export $BACKUP_DIR/definitions.json
# 备份配置
cp -r /etc/rabbitmq $BACKUP_DIR/
# 备份数据目录
cp -r /var/lib/rabbitmq/mnesia $BACKUP_DIR/
# 记录当前状态
rabbitmqctl status > $BACKUP_DIR/status.txt
rabbitmqctl cluster_status > $BACKUP_DIR/cluster_status.txt
rabbitmqctl list_queues name messages > $BACKUP_DIR/queues.txt
echo "备份完成: $BACKUP_DIR"
3. 检查清单
- [ ] 备份定义文件
- [ ] 备份配置文件
- [ ] 记录当前队列消息数
- [ ] 确认 Erlang 版本兼容
- [ ] 阅读版本发布说明
- [ ] 准备回滚方案
- [ ] 通知相关团队
- [ ] 选择低峰时段
📦 单节点升级
Linux (包管理)
#!/bin/bash
# upgrade-single-node.sh
echo "=== RabbitMQ 单节点升级 ==="
# 1. 停止服务
echo "停止 RabbitMQ 服务..."
systemctl stop rabbitmq-server
# 2. 升级 Erlang(如需要)
echo "升级 Erlang..."
# Ubuntu/Debian
apt-get update
apt-get install -y erlang
# CentOS/RHEL
# yum update erlang
# 3. 升级 RabbitMQ
echo "升级 RabbitMQ..."
# Ubuntu/Debian
apt-get install -y rabbitmq-server
# CentOS/RHEL
# yum update rabbitmq-server
# 4. 启动服务
echo "启动 RabbitMQ 服务..."
systemctl start rabbitmq-server
# 5. 等待启动
sleep 10
# 6. 验证
echo "验证升级结果..."
rabbitmqctl status | grep -E "RabbitMQ|Erlang"
rabbitmq-diagnostics check_running
echo "=== 升级完成 ==="
Docker 升级
#!/bin/bash
# upgrade-docker.sh
CONTAINER_NAME="rabbitmq"
NEW_VERSION="3.13-management"
BACKUP_DIR="/backup/rabbitmq-docker-$(date +%Y%m%d)"
mkdir -p $BACKUP_DIR
# 1. 备份
echo "备份当前数据..."
docker exec $CONTAINER_NAME rabbitmqadmin export /tmp/definitions.json
docker cp $CONTAINER_NAME:/tmp/definitions.json $BACKUP_DIR/
# 2. 停止旧容器
echo "停止旧容器..."
docker stop $CONTAINER_NAME
docker rename $CONTAINER_NAME ${CONTAINER_NAME}_old
# 3. 启动新版本容器
echo "启动新版本..."
docker run -d \
--name $CONTAINER_NAME \
-p 5672:5672 \
-p 15672:15672 \
-v rabbitmq_data:/var/lib/rabbitmq \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin123 \
rabbitmq:$NEW_VERSION
# 4. 等待启动
sleep 30
# 5. 验证
echo "验证升级结果..."
docker exec $CONTAINER_NAME rabbitmqctl status | grep RabbitMQ
# 6. 清理旧容器(确认无问题后)
# docker rm ${CONTAINER_NAME}_old
echo "=== 升级完成 ==="
🌐 集群升级
滚动升级
滚动升级允许在不停机的情况下逐个升级节点。
#!/bin/bash
# rolling-upgrade.sh
NODES=("rabbit@node1" "rabbit@node2" "rabbit@node3")
for NODE in "${NODES[@]}"; do
echo "=== 升级节点: $NODE ==="
# 1. 停止节点应用
ssh $NODE "rabbitmqctl stop_app"
# 2. 升级软件包
ssh $NODE "apt-get update && apt-get install -y rabbitmq-server"
# 3. 启动节点
ssh $NODE "rabbitmqctl start_app"
# 4. 等待同步
echo "等待节点同步..."
sleep 60
# 5. 验证节点状态
rabbitmqctl cluster_status | grep $NODE
echo "节点 $NODE 升级完成"
echo ""
done
echo "=== 集群升级完成 ==="
rabbitmqctl cluster_status
蓝绿部署
对于重大版本升级,建议使用蓝绿部署:
┌─────────────────────────────────────────────────────────┐
│ 负载均衡器 │
└─────────────────────────┬───────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
▼ │ ▼
┌─────────────────┐ │ ┌─────────────────┐
│ 蓝色集群 │ │ │ 绿色集群 │
│ (当前版本) │ │ │ (新版本) │
│ │ │ │ │
│ rabbitmq-blue │ │ │ rabbitmq-green │
└─────────────────┘ │ └─────────────────┘
↑ │ ↑
│ │ │
┌─────┴───────────────┴───────────────┴─────┐
│ Shovel │
│ (消息同步) │
└─────────────────────────────────────────────┘
#!/bin/bash
# blue-green-upgrade.sh
# 1. 部署绿色集群(新版本)
docker-compose -f docker-compose-green.yml up -d
# 2. 配置 Shovel 同步消息
rabbitmqctl set_parameter shovel blue-to-green \
'{
"src-uri": "amqp://admin:password@blue-cluster",
"src-queue": "important.queue",
"dest-uri": "amqp://admin:password@green-cluster",
"dest-queue": "important.queue"
}'
# 3. 验证绿色集群
# 运行测试...
# 4. 切换流量(修改负载均衡配置)
# 更新 nginx/haproxy 配置
# 5. 等待蓝色集群队列清空
while true; do
MESSAGES=$(rabbitmqctl -n rabbit@blue list_queues messages | awk '{sum+=$1} END {print sum}')
if [ "$MESSAGES" -eq 0 ]; then
break
fi
echo "等待消息消费完成,剩余: $MESSAGES"
sleep 10
done
# 6. 停止蓝色集群
docker-compose -f docker-compose-blue.yml down
echo "蓝绿部署完成"
⚠️ 版本特性变化
3.12 → 3.13 重要变化
- Classic Queues v2 成为默认
- 改进的流处理性能
- OAuth 2.0 改进
3.x → 4.0 重要变化
- 移除对经典镜像队列的支持(使用仲裁队列替代)
- Khepri 元数据存储(可选)
- AMQP 1.0 原生支持
- 改进的 OAuth 2.0 支持
迁移检查
#!/bin/bash
# check-migration.sh
echo "=== 升级兼容性检查 ==="
# 检查镜像队列(4.0 移除)
echo "检查镜像队列..."
MIRROR_POLICIES=$(rabbitmqctl list_policies | grep "ha-mode")
if [ -n "$MIRROR_POLICIES" ]; then
echo "⚠️ 发现镜像队列策略,需要迁移到仲裁队列:"
echo "$MIRROR_POLICIES"
fi
# 检查废弃的配置
echo "检查废弃配置..."
if grep -q "cluster_partition_handling" /etc/rabbitmq/rabbitmq.conf 2>/dev/null; then
echo "⚠️ 发现废弃配置: cluster_partition_handling"
fi
# 检查队列类型
echo "队列类型统计..."
rabbitmqctl list_queues name arguments | while read line; do
if echo "$line" | grep -q "quorum"; then
echo "仲裁队列: $(echo $line | awk '{print $1}')"
elif echo "$line" | grep -q "stream"; then
echo "流队列: $(echo $line | awk '{print $1}')"
else
echo "经典队列: $(echo $line | awk '{print $1}')"
fi
done
🔄 回滚方案
单节点回滚
#!/bin/bash
# rollback-single.sh
BACKUP_DIR=$1
if [ -z "$BACKUP_DIR" ]; then
echo "用法: $0 <backup_directory>"
exit 1
fi
echo "=== 开始回滚 ==="
# 1. 停止服务
systemctl stop rabbitmq-server
# 2. 卸载新版本
apt-get remove rabbitmq-server
# 3. 安装旧版本
dpkg -i $BACKUP_DIR/rabbitmq-server_*.deb
# 4. 恢复配置
cp -r $BACKUP_DIR/rabbitmq/* /etc/rabbitmq/
# 5. 恢复数据
rm -rf /var/lib/rabbitmq/mnesia
cp -r $BACKUP_DIR/mnesia /var/lib/rabbitmq/
chown -R rabbitmq:rabbitmq /var/lib/rabbitmq
# 6. 启动服务
systemctl start rabbitmq-server
echo "=== 回滚完成 ==="
Docker 回滚
#!/bin/bash
# rollback-docker.sh
CONTAINER_NAME="rabbitmq"
# 1. 停止新容器
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
# 2. 恢复旧容器
docker rename ${CONTAINER_NAME}_old $CONTAINER_NAME
docker start $CONTAINER_NAME
echo "Docker 回滚完成"
📝 本章小结
升级检查清单
| 阶段 | 检查项 |
|---|---|
| 升级前 | 备份、版本兼容、发布说明 |
| 升级中 | 逐步升级、验证每个节点 |
| 升级后 | 功能验证、性能测试、监控 |
升级策略选择
| 策略 | 适用场景 | 停机时间 |
|---|---|---|
| 单节点直接升级 | 开发/测试环境 | 短暂 |
| 滚动升级 | 小版本升级 | 无 |
| 蓝绿部署 | 大版本升级 | 无 |
常见问题
| 问题 | 解决方案 |
|---|---|
| Erlang 版本不兼容 | 先升级 Erlang |
| 插件不兼容 | 检查插件版本 |
| 配置格式变化 | 参考迁移文档 |
| 队列数据丢失 | 从备份恢复 |
恭喜完成!
你已经学完了 RabbitMQ 高级篇的所有内容!现在你具备了运维和管理 RabbitMQ 的专业技能。
