去年我们生产环境使用的RabbitMQ 3.9.11集群开始出现周期性连接中断问题,平均每72小时就会发生一次全集群连接闪断。查看日志发现大量如下报错:
code复制=ERROR REPORT==== 15-Jul-2023::03:22:11 ===
** Connection attempt from disallowed node 'rabbit@node3' **
更诡异的是,断连后约30秒会自动恢复,但部分队列会出现消息堆积。我们决定升级到当时最新的4.2.1版本寻求修复,没想到升级过程比预期复杂得多。
通过对比官方Release Notes,发现几个关键变化点:
我们采用三级备份方案:
rabbitmqctl export_definitions /backup/defs.json/var/lib/rabbitmq/mnesia目录rabbitmq.conf、enabled_plugins等重要提示:备份时务必停止服务,否则可能导致数据不一致
首先需要升级Erlang到25.3.2版本。在Ubuntu 20.04上操作:
bash复制# 添加Erlang Solutions仓库
wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb
sudo dpkg -i erlang-solutions_2.0_all.deb
# 安装指定版本
sudo apt-get update
sudo apt-get install esl-erlang=1:25.3.2-1
验证安装:
bash复制erl -version
Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version 13.2.3
下载4.2.1的deb包并安装:
bash复制wget https://github.com/rabbitmq/rabbitmq-server/releases/download/v4.2.1/rabbitmq-server_4.2.1-1_all.deb
sudo dpkg -i rabbitmq-server_4.2.1-1_all.deb
配置迁移注意事项:
rabbitmq.config需要转换为新的rabbitmq.conf格式bash复制rabbitmq-plugins enable rabbitmq_management rabbitmq_prometheus
新版本对节点加入有更严格验证。需要在第一个节点执行:
bash复制rabbitmqctl set_cluster_name production_cluster
rabbitmqctl set_cluster_secret my_secure_secret
其他节点加入时需携带secret:
bash复制rabbitmqctl join_cluster rabbit@node1 --ram --secret my_secure_secret
新版本引入了更智能的网络分区检测:
conf复制# rabbitmq.conf新增配置
cluster_partition_handling = pause_minority
最终定位到是旧版本的TCP缓冲区设置不当:
conf复制# 新增配置解决
tcp_listen_options.backlog = 1024
tcp_listen_options.nodelay = true
tcp_listen_options.linger.on = true
tcp_listen_options.linger.timeout = 0
新版本的内存计算方式导致我们的监控告警误报:
bash复制# 获取真实内存使用
rabbitmq-diagnostics memory_breakdown
需要调整告警阈值计算公式:
code复制总内存限制 = 0.7 * (服务器内存 - 系统预留)
升级前后关键指标对比:
| 指标 | 3.9.11 | 4.2.1 | 提升 |
|---|---|---|---|
| 消息吞吐量 | 12k msg/s | 18k msg/s | 50% |
| 连接稳定性 | 72h断连 | 无异常 | - |
| 内存占用 | 4.2GB | 3.7GB | 12%↓ |
| CPU使用率 | 65% | 52% | 20%↓ |
虽然升级成功,但我们仍准备了完善的回滚方案:
数据回滚:
bash复制rabbitmqctl stop_app
rm -rf /var/lib/rabbitmq/mnesia
tar -xzf /backup/mnesia.tar.gz -C /var/lib/rabbitmq/
rabbitmqctl start_app
配置回滚:
bash复制dpkg -i rabbitmq-server_3.9.11-1_all.deb
监控指标调整:
queue_sync_process监控mem_used告警阈值计算方式客户端适配:
java复制// Java客户端需要更新心跳设置
ConnectionFactory factory = new ConnectionFactory();
factory.setRequestedHeartbeat(60); // 从30提升到60
定期维护:
bash复制# 新增月度维护任务
rabbitmqctl eval 'supervisor2:restart_child(rabbit_channel_sup).'
这次升级最大的教训是:RabbitMQ的版本升级不仅仅是简单的包替换,需要全面考虑Erlang版本、配置格式、集群协议等多维度变化。我们花了三天时间完成全流程,但换来的是更稳定的消息服务。