版本升级

安全地升级 RabbitMQ 版本是运维的重要工作,需要充分准备和测试。

🎯 本章目标

  • 了解版本升级的注意事项
  • 掌握单节点和集群升级流程
  • 学会处理升级中的常见问题

📋 升级前准备

1. 版本兼容性检查

# 查看当前版本
rabbitmqctl status | grep -E "RabbitMQ|Erlang"

# 检查 Erlang 版本要求
# RabbitMQ 3.12 需要 Erlang 25.x 或 26.x
# RabbitMQ 4.x 需要 Erlang 26.x+

版本兼容性矩阵

RabbitMQErlang 最低Erlang 推荐
3.12.x25.026.x
3.13.x26.026.x
4.0.x26.226.x
4.1.x26.226.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 的专业技能。