Nacos不支持真正的热升级,因内存结构、数据库表和gRPC协议三类强耦合变更导致新旧节点无法共存,必须逐节点停服滚动升级。

不能真正“在线”完成 Nacos 集群的版本平滑升级 —— 所有官方支持的升级路径(包括 2.0→2.5.1)都要求逐节点停服、替换、重启,不存在零停机热升级机制。所谓“不停机”,本质是靠集群冗余 + 逐台滚动操作来掩盖单点不可用,客户端需配合健康检查与重试逻辑才能感知不到抖动。
为什么 Nacos 不支持真正的热升级
Nacos 升级不是改个配置就能生效的事。它涉及三类强耦合变更:
-
内存数据结构:比如 2.0 引入的raft元数据分片模型,与 1.x 的standalone内存注册表不兼容 -
数据库表结构:从 2.0 开始新增config_info_tag、tenant_info等表,字段类型和索引也调整过多次 -
gRPC 协议版本:2.0+ 默认启用 gRPC 作为服务同步通道,1.x 客户端无法解析其帧格式
这些变更导致新旧节点无法共存于同一集群 —— 启动即报 Cluster protocol mismatch 或直接拒绝加入集群。
实际可行的滚动升级操作要点
以 2.4.1 → 2.5.1(MySQL 持久化、JDK8、Linux jar 包部署)为例,必须按顺序执行:
- 确认所有节点
application.properties中nacos.core.support.upgrade.from.1x未被设为true(该配置仅对 1.x→2.1.x 有效,2.4.x 升级时设了反而触发异常校验) - 逐台操作:停
sh shutdown.sh→ 备份本机logs/和data/目录 → 替换bin/和target/nacos-server-*.jar→ 更新conf/application.properties中的db.url.0(若地址有变)→ 执行sh startup.sh -m cluster - 每台启动后,立刻验证:
curl -s http://localhost:8848/nacos/v1/ns/operator/metrics | grep "raft" | wc -l返回非 0 表示 raft 节点已就绪;再查/nacos/v1/ns/service/list确认实例数无丢失 - 严禁跳过
cluster.conf同步:新版本会严格校验该文件中所有 IP:port 是否可达,少写或错写会导致节点卡在WAITING_FOR_CHECK状态
元数据备份不能只靠 mysqldump
单纯导出 MySQL 数据库(如 mysqldump -u root -p nacos > backup.sql)只能覆盖配置中心数据,漏掉三类关键元数据:
-
服务实例心跳状态:这部分存在内存里,MySQL 中只有最终快照(instance表),没存历史心跳时间戳 -
客户端长连接上下文:gRPC 连接绑定的 session id、推送序列号等,全部在 JVM heap 中,关机即丢 -
权限缓存:开启鉴权后,nacos.core.auth.caching.enabled=true时,token 解析结果缓存在本地 Caffeine 中,不落库
真正可靠的元数据备份动作是:
- 升级前,在每台节点上执行:
curl -X GET "http://localhost:8848/nacos/v1/ns/operator/servers?healthyOnly=false",保存返回的全部节点列表及健康状态 - 用
curl -X GET "http://localhost:8848/nacos/v1/ns/instance/list?serviceName=*&withInstances=true"导出全量服务实例快照(注意加pageSize分页) - 手动复制
conf/application.properties和conf/cluster.conf到安全位置 —— 这两个文件一旦出错,整个集群无法自愈
最易被忽略的一点:升级后首次启动时,Nacos 会自动执行 DDL 变更(如新增字段、建索引),这个过程阻塞所有读写请求。如果数据库连接池设置过小(默认 druid.initialSize=5),可能因锁表时间过长导致客户端超时失败。建议提前把 druid.maxActive 调到 20 以上,并在低峰期执行首节点升级。

















