Skip to content

Nacos 集群

单节点 Nacos 只适合本地开发验证。真正给一组应用使用时需要集群——目的不是多开几个控制台页面,而是让配置读取、服务注册和客户端连接不因为一个 Nacos 进程挂掉就整体不可用。这篇讲集群怎么搭、怎么验证、节点故障时怎么办。

一、集群结构

三节点 Nacos + 一套 MySQL 是最小的集群形态:

三个节点是比较常见的起点:两个节点出现网络分区时无法区分"对方挂了"和"网络断了",三个节点用奇数投票不会出现平局。节点过多则通信和维护成本变高。实验里 MySQL 还是单点,所以这只是 Nacos 服务层的集群验证——生产环境中 MySQL 也要做高可用,不然 Nacos 集群再稳,MySQL 一挂全完。

二、cluster.conf

cluster.conf 是节点互相识别的入口:

text
192.168.10.11:8848
192.168.10.12:8848
192.168.10.13:8848

三台机器内容必须完全一致。写的是 8848(服务端 API 端口),不是控制台 8080如果某台节点没写进 cluster.conf,它可能自己启动但不加入集群——进程在跑,端口在监听,但集群管理页面看不到它。这种状态排查起来很费劲,因为你以为它入群了,其实没有。

三、通信端口

节点之间需要互通的端口不止 HTTP:

端口用途互访要求
8848HTTP API节点间需要互通
9848客户端 gRPC业务应用到 Nacos
9849服务端 gRPC节点之间必须互通
7848集群一致性(Raft)通信节点之间必须互通
bash
# 每台节点确认端口监听
ss -lntp | egrep ':(8848|9848|9849|7848)\b'

# 从一台测试到另一台的连通性
nc -vz 192.168.10.12 8848
nc -vz 192.168.10.12 9848
nc -vz 192.168.10.12 9849
nc -vz 192.168.10.12 7848

本机监听正常只说明进程启动成功。防火墙、安全组、路由问题仍然可能让节点间看不见彼此。排查一个集群中"只有本机"的问题时,先从端口连通性查起——十有八九是某几个节点间端口没通。

四、外部 MySQL

三台 Nacos 指向同一个 MySQL 数据库,目的是看到同一套配置、用户和权限数据:

properties
spring.sql.init.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.10.11:3306/nacos_config?characterEncoding=utf8&connectTimeout=10000&socketTimeout=30000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
db.user.0=nacos
db.password.0=Nacos@123456

Nacos 里不同类型数据的一致性机制不一样,这个区别要记住:配置数据靠 MySQL 保证持久化和多节点读一致;服务实例(临时的)靠心跳 + 节点间 gRPC 同步 + 客户端缓存;权限和用户存在 MySQL,三节点共享同一份。

临时服务实例的一致性不是靠 MySQL,而是靠节点间的 gRPC 同步。当一个临时实例向节点 A 注册后,节点 A 会通过 gRPC 把这个变更同步给节点 B 和节点 C。如果节点间 gRPC 端口(9849)不通,各节点上看到的服务列表就可能不一致——A 节点上有这个实例,B 节点上没有。这种"各节点数据不一致"特别坑,排查时要从节点间通信入手。

验证配置数据一致性的直接方式——分别从三节点读同一配置,返回一致才算通过。

五、集群管理页面

控制台集群管理页面能看到节点列表,核心关注:节点数量(等于 cluster.conf 里配置的数量)、节点状态(全部为 UP)、版本(三台一致)、Raft 端口(正确)。

节点状态 UP 表示集群视角下该节点可用。如果节点数量少了一台:先看那台的 Nacos 进程是否在跑 → cluster.conf 内容是否一致 → 通信端口是否互通,顺着这三步查基本能定位。

六、节点故障影响

单个 Nacos 节点故障后,客户端能否自动切换取决于接入方式:客户端写多个 Nacos 地址时依赖 SDK 重试其他地址;前面放负载均衡(VIP/域名)时应用只连一个入口,负载均衡需对 Nacos 做健康检查;K8s 内部 Service 时集群内应用通过 Service 访问,K8s 负责转发。

客户端写多个地址时,SDK 的行为通常是:连第一个地址,失败后尝试第二个。但这个切换不是瞬间的——取决于客户端的连接超时和重试间隔。如果第一个地址的机器是宕机(而不是端口拒绝连接),客户端可能要等 TCP 连接超时(几十秒)才会切到下一个地址。

负载均衡的健康检查不能只看端口通不通——端口通但 Nacos 内部接口异常时,负载均衡仍会把流量下发到故障节点。健康检查应该访问 Nacos 的实际接口,比如登录 API 或配置读取 API:

bash
# 比单纯 TCP 端口检查更可靠——验证 Nacos 内部业务是否正常
curl -sS -o /dev/null -w '%{http_code}' \
  -X POST 'http://192.168.10.11:8848/nacos/v3/auth/user/login' \
  -d 'username=nacos&password=nacos'

七、升级与维护

滚动操作方式:

text
1. 停止一个节点(或从负载均衡摘除)
2. 确认业务客户端仍在连接其他节点(看其他节点的连接和日志)
3. 升级或修改该节点的配置
4. 启动,确认控制台状态回到 UP
5. 观察一段时间(配置读写、服务注册恢复正常)
6. 再操作下一台

升级前备份:MySQL 数据库、application.propertiescluster.conf、systemd unit。Nacos 版本升级可能涉及配置项改名、数据库 schema 变更、API 路径变化——不能只替换二进制包

升级前还要确认三件事:release notes 里有没有数据库 schema 变更(需要先执行升级脚本)、配置项名称有没有变化(旧配置项可能已被废弃)、API 版本是否兼容(客户端 SDK 版本和服务端版本不一定能混用)。这三件事不确认就直接升,基本等着出事。

八、集群异常

现象排查方向
节点启动但不入集群cluster.conf 内容不一致、节点间端口不通
控制台只看到一个节点其他节点的进程、端口、cluster.conf
配置发布失败MySQL 连接、鉴权配置、数据库 schema 版本
某节点读到配置异常该节点的 MySQL 连接或鉴权参数与其他节点不一致
服务实例频繁掉线客户端心跳间隔、网络抖动、gRPC 端口不通
版本显示不一致软链接指向不同版本目录,升级不完整

集群排查的效率取决于是否三台一起对比——配置文件、进程参数、端口监听、日志时间点、控制台节点列表。单独看一台,很容易漏掉"只有这一台配得不一样"的问题。

具体做法:

bash
# 三台同时执行,输出并排对比
for host in 192.168.10.11 192.168.10.12 192.168.10.13; do
  echo "========== ${host} =========="
  ssh ${host} "cat /opt/nacos/conf/cluster.conf"
  ssh ${host} "ss -lntp | egrep ':(8848|9848|9849|7848)\b'"
  echo
done

三台输出完全一致才算集群配置对齐。任何一行的差异都可能是异常的来源——这个"三台对比"的思路,是集群运维的基本功。