Nacos
本文范围
你做一个单体项目时,配置写在 application.yml 里,服务地址写死也能跑。等系统拆成十几个、几十个服务后,麻烦就来了:
- 服务 A 要调用服务 B,不能每次都改 IP。
- 服务扩容、缩容、发布、下线后,调用方要能自动感知。
- 数据库地址、开关、限流阈值、第三方接口地址不能散在每台机器的配置文件里。
- 配置改错后要能查历史、能回滚、能知道哪些客户端监听了它。
Nacos 主要就是干这两件事:
- 注册中心:服务启动后把自己的服务名、IP、端口、权重、健康状态注册上来,调用方按服务名发现实例。
- 配置中心:配置统一放到 Nacos,应用启动时拉取,运行时监听变更。
这里要注意,Nacos 不是万能中间件。它不替你设计业务配置模型,也不替你做完整密钥管理,更不等于 Spring Cloud Alibaba 全家桶。本文只讲 Nacos 本身:怎么部署,怎么连数据库,怎么隔离配置,怎么注册服务,怎么开鉴权,怎么备份,出问题怎么查。
当前写作时间是 2026-07-09。官方 Release History 显示 Nacos 当前 GA 最新版本是 3.2.2,Nacos 3.x 需要 Java 17。老项目里常见的 Nacos 2.x 仍然是 Java 8 体系,所以你看旧资料时一定要先问一句:这是 2.x 还是 3.x?
后面的命令按 Nacos 3.2.2 写,遇到 2.x 差异会单独提醒。
前置条件
Nacos 是注册配置中心,生产部署前先把这些条件定死:
- Java 版本:Nacos 3.x 使用 Java 17;仍在 Nacos 2.x 的老项目要按 2.x 文档校准。
- 节点数量:生产集群至少 3 个 Nacos 节点,节点列表放在内网 SLB 或内网域名后面。
- 数据库:生产不要用内置数据库,准备 MySQL 兼容数据库、初始化 SQL、备份账号和恢复流程。
- 端口:控制台、HTTP API、客户端 gRPC、节点间 gRPC 和一致性通信端口要分清访问范围。
- 权限:默认管理员密码、JWT secret、应用账号、配置发布权限和审计记录都不能使用示例值。
先准备机器、端口和软件包
别急着启动,Nacos 这种注册配置中心,最怕的是“服务看起来启动了,客户端就是连不上”。先把端口和依赖摆清楚。
Nacos 3.x 常用端口如下:
| 端口 | 用途 | 怎么放行 |
|---|---|---|
8080 | 控制台默认端口 | 只给运维、研发内网或堡垒机 |
8848 | 服务端 HTTP API | 给客户端和内部管理工具 |
9848 | 客户端 gRPC 通信 | 给客户端或入口 TCP 转发 |
9849 | Nacos 节点之间 gRPC 通信 | 只允许 Nacos 节点互通 |
7848 | 集群内部一致性通信 | 只允许 Nacos 节点互通 |
如果你用的是 Nacos 2.x,控制台通常还是 8848/nacos,这点和 3.x 不一样。很多人新装 3.x 后访问 http://IP:8848/nacos,打不开就以为服务坏了,其实控制台已经换到 8080 了。
先在机器上检查 Java:
java -versionNacos 3.x 看到 Java 17 才对。比如:
openjdk version "17.x.x"如果看到的是 Java 8,先别继续装 3.x。要么换 JDK 17,要么你就按 Nacos 2.x 的版本体系部署。
端口先查一下有没有被占用:
ss -lntp | grep -E '8080|8848|9848|9849|7848'没有输出,说明这些端口当前没有监听。已经有输出,就看最后一列是哪个进程占用了端口。生产机器不要随便 kill,先确认是不是已经有旧 Nacos 或别的中间件在跑。
目录也提前建好:
useradd -r -m -s /sbin/nologin nacos
mkdir -p /opt/nacos /data/nacos/{logs,data,backup}
chown -R nacos:nacos /opt/nacos /data/nacos这里做了三件事:
- 新建
nacos系统用户,避免一直用 root 跑服务。 /opt/nacos放程序包。/data/nacos放日志、运行数据和备份,方便后面扩盘和迁移。
如果你是内网或离线环境,提前把这些东西放到内部制品库:
nacos-server-3.2.2.tar.gz- JDK 17 安装包
- Nacos Docker 镜像
nacos/nacos-server:v3.2.2 - MySQL 安装包或镜像
- 对应版本的数据库初始化 SQL
- 每个包的
sha256sum
下载完先做校验:
sha256sum nacos-server-3.2.2.tar.gz这一步不是形式主义。离线交付时,包在 U 盘、跳板机、制品库之间拷来拷去,文件坏了很难第一时间看出来。校验和能帮你把问题拦在启动之前。
先用单机模式跑起来
单机模式适合学习、开发环境和功能验证。生产不要只跑单机,因为配置中心挂了,会影响应用启动、配置刷新和服务发现。
解压 Nacos:
tar -zxvf nacos-server-3.2.2.tar.gz -C /opt/nacos
ln -sfn /opt/nacos/nacos /opt/nacos/current
chown -R nacos:nacos /opt/nacos/current /opt/nacos/nacos这里的软链接 current 是为了后面升级方便。以后从 3.2.2 升到新版本,只要换软链接和配置,不用到处改脚本路径。
Nacos 3.x 启动前一般要准备鉴权相关参数。学习环境可以按启动脚本提示输入,实际部署建议直接写到配置文件里:
cd /opt/nacos/current
AUTH_TOKEN="$(openssl rand -base64 48)"
IDENTITY_VALUE="$(openssl rand -base64 32)"
cat >> conf/application.properties <<EOF
nacos.core.auth.plugin.nacos.token.secret.key=${AUTH_TOKEN}
nacos.core.auth.server.identity.key=nacos_server_identity
nacos.core.auth.server.identity.value=${IDENTITY_VALUE}
EOF这三个配置分别解决:
- token secret:用来签发和校验登录 token。
- identity key/value:Nacos 节点之间互相识别身份。
- 集群时这些值必须一致,单机时也先按生产习惯配好。
启动单机:
su -s /bin/bash nacos -c 'bin/startup.sh -m standalone'-m standalone 表示单机模式。不要在生产集群里加这个参数,集群模式直接用 bin/startup.sh。
看启动结果:
jps -l | grep -i nacos
tail -n 100 logs/start.out
tail -n 100 logs/nacos.log正常情况下,你应该能看到 Nacos 进程,并且日志里没有明显的 ERROR、Exception、port already in use。
再访问控制台:
http://服务器IP:8080/看到登录或初始化页面,说明控制台起来了。如果访问 8080 不通,先查端口:
ss -lntp | grep 8080如果 8080 没监听,看启动日志;如果 8080 监听了但浏览器打不开,看防火墙、安全组、反向代理。
再测一下服务端 API:
curl -i 'http://127.0.0.1:8848/nacos/v3/client/ns/instance/list?serviceName=quickstart.test.service'这里查的是一个不存在的测试服务。重点不是返回多少实例,而是 HTTP 能不能正常返回。如果连接被拒绝,说明 8848 没起来;如果超时,先查防火墙或服务进程。
停止服务:
su -s /bin/bash nacos -c 'bin/shutdown.sh'停止后再查:
jps -l | grep -i nacos没有输出才算停干净。
用 systemd 管起来
手动执行 startup.sh 适合调试,不适合生产。生产上要能开机自启、失败重启、统一看日志,所以一般用 systemd。
新建服务文件:
[Unit]
Description=Nacos Server
After=network.target
[Service]
Type=forking
User=nacos
Group=nacos
WorkingDirectory=/opt/nacos/current
Environment="JAVA_HOME=/usr/lib/jvm/jdk-17"
Environment="JAVA_OPT_EXT=-Xms1g -Xmx1g -Xmn512m"
ExecStart=/opt/nacos/current/bin/startup.sh
ExecStop=/opt/nacos/current/bin/shutdown.sh
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target保存后加载:
systemctl daemon-reload
systemctl enable nacos
systemctl start nacos
systemctl status nacos --no-pager看到 active (running) 就说明 systemd 认为服务正常。如果失败,先不要猜,直接看:
journalctl -u nacos -n 200 --no-pager
tail -n 200 /opt/nacos/current/logs/start.out
tail -n 200 /opt/nacos/current/logs/nacos.log一般启动失败就这几类原因:
JAVA_HOME写错。- Java 版本不对。
- 端口被占用。
- JVM 内存给太大,机器扛不住。
- 鉴权参数没配。
- 外置数据库连不上。
修复完不要只看 systemctl status,再用 curl 测一次 8848,用浏览器测一次 8080。
用 Docker 快速跑一版
如果只是想快速体验,Docker 更快。这里要注意:Docker 方式也不能用 latest,必须固定版本。
先跑一个最小容器:
docker run -d --name nacos \
-p 8080:8080 \
-p 8848:8848 \
-p 9848:9848 \
-e MODE=standalone \
nacos/nacos-server:v3.2.2这条命令做了几件事:
-d后台运行。-p 8080:8080暴露控制台。-p 8848:8848暴露 HTTP API。-p 9848:9848暴露客户端 gRPC。MODE=standalone表示单机模式。
看日志:
docker logs -f --tail=200 nacos看到服务启动完成后,浏览器访问:
http://Docker宿主机IP:8080/如果访问不了,先看容器是否还在:
docker ps -a | grep nacos如果状态是 Exited,直接看日志。Nacos 容器启动失败,大概率是鉴权参数、内存、端口或配置挂载问题。
更接近生产的单机容器要把日志和数据挂出来,并且显式开启鉴权:
mkdir -p /data/nacos/{logs,conf,data}
NACOS_AUTH_TOKEN="$(openssl rand -base64 48)"
NACOS_AUTH_IDENTITY_KEY="nacos_server_identity"
NACOS_AUTH_IDENTITY_VALUE="$(openssl rand -base64 32)"
docker run -d --name nacos \
--restart=always \
-p 8080:8080 \
-p 8848:8848 \
-p 9848:9848 \
-e MODE=standalone \
-e JVM_XMS=1g \
-e JVM_XMX=1g \
-e JVM_XMN=512m \
-e NACOS_AUTH_ENABLE=true \
-e NACOS_AUTH_TOKEN="${NACOS_AUTH_TOKEN}" \
-e NACOS_AUTH_IDENTITY_KEY="${NACOS_AUTH_IDENTITY_KEY}" \
-e NACOS_AUTH_IDENTITY_VALUE="${NACOS_AUTH_IDENTITY_VALUE}" \
-v /data/nacos/logs:/home/nacos/logs \
-v /data/nacos/conf:/home/nacos/conf \
-v /data/nacos/data:/home/nacos/data \
nacos/nacos-server:v3.2.2这里要注意,NACOS_AUTH_TOKEN 和 NACOS_AUTH_IDENTITY_VALUE 是运行前生成的,不要每次重启都重新生成。否则你今天启动一次是一个值,明天重建容器又换一个值,客户端和集群节点就会出现一堆 401、403。
生产建议把这些值放到部署平台变量、密钥管理系统或受控配置文件里。
配外置数据库
单机试一下可以用内置存储。只要进生产,建议接外置数据库。原因很简单:配置、历史记录、用户权限、命名空间这些东西不能跟着某一个 Nacos 节点走。
先建库和账号:
CREATE DATABASE nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nacos'@'%' IDENTIFIED BY 'change_me_to_a_strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX ON nacos_config.* TO 'nacos'@'%';
FLUSH PRIVILEGES;这里不要直接用 root。Nacos 只需要管理自己的库,给独立账号就可以。
接着导入初始化 SQL。SQL 文件名要以你当前版本包里的文件为准,先找一下:
cd /opt/nacos/current
find conf -maxdepth 2 -type f | grep -Ei 'mysql|schema|sql'找到以后导入:
mysql -h mysql.example.com -P 3306 -unacos -p nacos_config < conf/mysql-schema.sql如果这里报 No such file,说明 SQL 文件名不是这个;如果报 Access denied,就是账号或权限问题;如果报连接超时,先查数据库端口:
nc -vz mysql.example.com 3306配置 Nacos 数据源:
spring.sql.init.platform=mysql
db.num=1
db.url.0=jdbc:mysql://mysql.example.com:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
db.user.0=nacos
db.password.0=change_me_to_a_strong_password这里最容易踩坑的是旧资料里的 spring.datasource.platform=mysql。不同 Nacos 版本参数可能有差异,正式部署前按你选定版本的官方系统参数校准,不要拿旧博客里的配置硬套。
重启 Nacos:
systemctl restart nacos
tail -n 200 /opt/nacos/current/logs/nacos.log再查数据库里有没有表:
mysql -h mysql.example.com -P 3306 -unacos -p nacos_config -e "SHOW TABLES;"看到 config_info、his_config_info 等配置相关表,说明初始化成功。后面发布配置时,也可以查一下数量变化:
mysql -h mysql.example.com -P 3306 -unacos -p nacos_config -e "SELECT COUNT(*) FROM config_info;"生产建议:
- 数据库要做备份。
- 数据库账号最小权限。
- 数据库连接串不要提交到公开仓库。
- Nacos 本地 dump 只是缓存,不是权威备份。
搭一个三节点集群
生产环境一般至少 3 个节点:
10.0.0.11 nacos-1
10.0.0.12 nacos-2
10.0.0.13 nacos-3三个节点共用同一个外置数据库。每台机器都解压同一版本 Nacos,配置同一套数据库参数和同一套鉴权参数。
先写 cluster.conf:
10.0.0.11:8848
10.0.0.12:8848
10.0.0.13:8848这里写的是每个 Nacos 节点的真实内网地址,不要写负载均衡地址,也不要写容器内部地址。写错了,节点之间会互相找不到。
然后确认端口互通:
for host in 10.0.0.11 10.0.0.12 10.0.0.13; do
nc -vz "$host" 8848
nc -vz "$host" 9848
nc -vz "$host" 9849
nc -vz "$host" 7848
done正常应该都能连通。哪个端口失败,就查哪个方向的防火墙、安全组、主机防火墙或容器端口映射。
三个节点都启动:
systemctl start nacos
systemctl status nacos --no-pager
tail -n 100 /opt/nacos/current/logs/nacos.log如果只有一台正常,另外两台报集群通信异常,先看 cluster.conf 是否三台一致,再看 9849 和 7848 是否互通。
入口层一般这样规划:
nacos-console.example.com:80/443 -> 10.0.0.11:8080,10.0.0.12:8080,10.0.0.13:8080
nacos-api.example.com:8848 -> 10.0.0.11:8848,10.0.0.12:8848,10.0.0.13:8848
nacos-api.example.com:9848 -> 10.0.0.11:9848,10.0.0.12:9848,10.0.0.13:9848这里要注意:9848 是 gRPC,不要只配普通 HTTP 代理。用 Nginx 的话,要用 stream 做 TCP 转发:
stream {
upstream nacos_grpc {
server 10.0.0.11:9848;
server 10.0.0.12:9848;
server 10.0.0.13:9848;
}
server {
listen 9848;
proxy_pass nacos_grpc;
}
}验证集群时,不要只看控制台能不能打开。还要做一次写入和查询:
curl -i 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance/list?serviceName=quickstart.test.service'然后登录控制台发布一条测试配置,分别从三个节点查一次。三个节点都能查到,说明数据库、节点缓存和入口基本没问题。
namespace、group、dataId 怎么规划
Nacos 配置中心定位一份配置,靠三个字段:
namespaceId + groupName + dataId通俗一点说:
namespace管大隔离,一般隔离环境,比如 dev、test、prod。group管分组,一般隔离业务线、应用组或公共配置。dataId就是具体配置文件名,比如order-service.yaml。
很多配置读不到的问题,最后都不是 Nacos 挂了,而是这三个字段没对上。
一般这样建:
namespace:
dev
test
pre
prod
group:
ORDER_GROUP
PAY_GROUP
COMMON_GROUP
dataId:
common.yaml
order-service.yaml
pay-service.yaml这里要注意,客户端配置里常用的是 namespace ID,不是页面上显示的名称。你在控制台新建 namespace 后,要复制它的 ID。
Spring Cloud Alibaba 客户端最小配置可以这样写:
spring:
application:
name: order-service
profiles:
active: prod
cloud:
nacos:
server-addr: nacos-api.example.com:8848
username: nacos_app_reader
password: change_me
config:
namespace: prod-namespace-id
group: ORDER_GROUP
file-extension: yaml
discovery:
namespace: prod-namespace-id
group: ORDER_GROUP启动后如果读不到配置,先不要怀疑框架,按顺序查:
server-addr能不能访问。- username/password 有没有权限。
- namespace ID 是否正确。
- group 是否一致。
- dataId 是否是
order-service.yaml或对应 profile 规则生成的名称。 yaml和properties后缀有没有写错。
共享配置可以用,但不要滥用:
spring:
cloud:
nacos:
config:
shared-configs:
- data-id: common.yaml
group: COMMON_GROUP
refresh: true
extension-configs:
- data-id: datasource.yaml
group: ORDER_GROUP
refresh: true经验上,公共配置、数据源配置、服务私有配置可以拆开;但不要拆出几十个小 dataId。配置链太长,排障时你会不知道到底哪一份覆盖了哪一份。
Nacos 注册与配置数据流图
下面这张图适合在方案评审和上线检查时一起过。它把“客户端怎么进来、注册中心保存什么、配置中心怎么发布、集群和外置库怎么兜底”放到同一张图里。只要其中一条线说不清,后面排障就很容易在控制台、客户端、数据库和入口层之间来回打转。
上线时可以按图反查三件事:第一,客户端入口是不是同时放通了 8848 和 9848,并且 9848 是 TCP 转发;第二,配置是否能用 namespaceId + groupName + dataId 查询到,发布后客户端日志是否刷新;第三,外置 MySQL、鉴权 secret、审计和备份是否已经纳入运维清单。
服务注册、发现和下线
我们先不用 Spring,直接用 OpenAPI 注册一个测试实例,理解 Nacos 注册中心到底保存了什么。
注册实例:
curl -X POST 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance' \
-d 'serviceName=demo-service' \
-d 'groupName=DEMO_GROUP' \
-d 'ip=10.0.1.10' \
-d 'port=8080' \
-d 'namespaceId=public' \
-d 'ephemeral=true'这条命令的意思是:把 10.0.1.10:8080 注册成 DEMO_GROUP 分组下的 demo-service 实例。
查询实例:
curl 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance/list?serviceName=demo-service&groupName=DEMO_GROUP&namespaceId=public'正常应该能看到实例列表。重点看几个字段:
ip和port是否正确。healthy是否为健康。enabled是否启用。ephemeral是否临时实例。
普通微服务一般用临时实例。临时实例的特点是:服务活着就注册,服务断开或心跳异常后会被摘除。发布时不要直接粗暴停进程,建议先下线或降权重,再停应用。
常见发布动作:
先看实例列表
-> 把目标实例权重调低或设置下线
-> 等待调用方刷新服务列表
-> 停应用
-> 部署新版本
-> 启动应用
-> 健康检查通过
-> 恢复权重如果下线后仍有流量,不一定是 Nacos 没生效。调用方本地可能还有服务列表缓存,网关或连接池也可能还握着旧连接。这个时候看网关日志和调用方日志,比盯着 Nacos 控制台更有用。
配置发布、监听和回滚
配置发布属于管理动作。Nacos 3.x 默认要求 Admin API 带 accessToken,所以先登录:
NACOS_ACCESS_TOKEN="$(
curl -s -X POST 'http://nacos-api.example.com:8848/nacos/v3/auth/user/login' \
-d 'username=nacos' \
-d 'password=change_me' \
| sed -n 's/.*"accessToken":"\([^"]*\)".*/\1/p'
)"
test -n "$NACOS_ACCESS_TOKEN" && echo "login ok"如果没有输出 login ok,先查用户名密码和鉴权配置,不要继续发配置。
发布一条测试配置:
curl -X POST 'http://nacos-api.example.com:8848/nacos/v3/admin/cs/config' \
-H "accessToken:${NACOS_ACCESS_TOKEN}" \
-d 'namespaceId=public' \
-d 'groupName=DEMO_GROUP' \
-d 'dataId=demo.yaml' \
-d 'type=YAML' \
--data-urlencode 'content=demo:
enabled: true
timeout: 3000'发布成功后,立刻查询:
curl 'http://nacos-api.example.com:8848/nacos/v3/client/cs/config?namespaceId=public&groupName=DEMO_GROUP&dataId=demo.yaml'应该能看到刚刚的 YAML 内容。如果发布成功但查询不到,一般查这几项:
- namespace 是不是
public。 - group 是否是
DEMO_GROUP。 - dataId 是否是
demo.yaml。 - 有没有命中另一个 Nacos 地址。
- 鉴权是否拦了客户端查询。
配置监听的原理可以这样理解:客户端不是每秒傻傻地全量拉配置,而是带着自己关注的 dataId + group + namespace 和本地 md5 去问服务端。服务端发现没变化,就把请求挂一会儿;有变化就通知客户端,客户端再去拉新配置。
这就是为什么配置不生效时要分两步看:
- Nacos 里配置有没有变。
- 客户端有没有收到变更并刷新本地 Bean。
回滚配置时,不建议直接复制某台机器上的 dump 文件。dump 是本地缓存,不是权威数据源。正确流程是:
控制台查看历史版本
-> 对比内容和变更人
-> 选择目标版本回滚
-> 查询当前配置
-> 看客户端日志是否刷新
-> 验证业务行为是否恢复生产改配置前,先做三件事:
- 导出当前配置。
- 确认影响哪些应用。
- 准备回滚版本。
这比事后到处找“之前那个配置是多少”靠谱得多。
权限和鉴权
Nacos 必须放在内网。官方也提醒过,默认鉴权不是给公网硬扛攻击用的。生产上第一原则就是:不要公网暴露控制台和 API。
服务端开启鉴权:
nacos.core.auth.enabled=true
nacos.core.auth.system.type=nacos
nacos.core.auth.plugin.nacos.token.secret.key=replace_with_base64_secret
nacos.core.auth.plugin.nacos.token.expire.seconds=18000
nacos.core.auth.server.identity.key=replace_with_identity_key
nacos.core.auth.server.identity.value=replace_with_identity_value
nacos.core.auth.enable.userAgentAuthWhite=false生成 secret:
openssl rand -base64 48这里要注意:
- 不要用公开示例里的 secret。
- 集群所有节点 secret 必须一样。
- 集群所有节点 identity key/value 必须一样。
- 不要让业务应用都用管理员账号。
客户端账号建议分开:
spring:
cloud:
nacos:
username: nacos_app_reader
password: change_me一般可以分这些账号:
- 平台管理员:管理用户、角色、namespace。
- 运维发布账号:发布、回滚、导入导出配置。
- 应用只读账号:读取配置、服务发现。
- 自动化账号:只给流水线需要的 namespace/group。
如果出现 401 或 403,先看:
grep -Ei "auth|token|identity|403|401" logs/nacos.log
grep -Ei "auth|token|identity|403|401" app.log如果是集群里只有某个节点报 403,大概率是这个节点的 token secret 或 identity 和其他节点不一致。
中国大陆、企业内网和离线部署
这里不要迷信某个镜像加速地址。国内网络和第三方镜像源变化很快,文章里写死一个地址,很容易半年后就不可用。
更稳的做法是:能访问外网的机器下载一次,校验后放到内部仓库。
Docker 镜像离线迁移:
docker pull nacos/nacos-server:v3.2.2
docker save nacos/nacos-server:v3.2.2 -o nacos-server-v3.2.2.tar
sha256sum nacos-server-v3.2.2.tar > nacos-server-v3.2.2.tar.sha256拷贝到内网后:
sha256sum -c nacos-server-v3.2.2.tar.sha256
docker load -i nacos-server-v3.2.2.tar
docker tag nacos/nacos-server:v3.2.2 harbor.example.com/middleware/nacos-server:v3.2.2
docker push harbor.example.com/middleware/nacos-server:v3.2.2二进制包离线交付也一样:
sha256sum nacos-server-3.2.2.tar.gz > nacos-server-3.2.2.tar.gz.sha256到内网机器后先校验:
sha256sum -c nacos-server-3.2.2.tar.gz.sha256离线交付包里至少放:
- Nacos 包或镜像。
- JDK 17。
- MySQL 包或镜像。
- 初始化 SQL。
- systemd 或 Compose 模板。
- 配置样例。
- 校验和文件。
- 回滚版本。
如果没有这些东西,现场部署时就会变成“缺一个包找一个包,缺一个镜像导一个镜像”,特别容易把环境搞乱。
备份和恢复
Nacos 备份不要只备份程序目录。真正重要的是数据库和配置导出。
数据库备份:
BACKUP_DIR=/data/nacos/backup
DATE=$(date +%F-%H%M%S)
mkdir -p "$BACKUP_DIR"
mysqldump \
-h mysql.example.com \
-P 3306 \
-unacos \
-p \
--single-transaction \
--routines \
--triggers \
nacos_config > "$BACKUP_DIR/nacos_config_$DATE.sql"
gzip "$BACKUP_DIR/nacos_config_$DATE.sql"
sha256sum "$BACKUP_DIR/nacos_config_$DATE.sql.gz" > "$BACKUP_DIR/nacos_config_$DATE.sql.gz.sha256"这条命令解决的是“配置和权限数据能不能恢复”的问题。--single-transaction 用来尽量减少备份时对线上读写的影响。
恢复演练:
gunzip -c nacos_config_2026-07-09-230000.sql.gz | mysql -h mysql-restore.example.com -unacos -p nacos_config
mysql -h mysql-restore.example.com -unacos -p nacos_config -e "SELECT COUNT(*) FROM config_info;"能导入只是第一步。恢复后还要启动一个 Nacos 测试节点,查询配置,发布配置,回滚配置,确认链路真的可用。
发布前建议额外导出目标 namespace 的配置。数据库备份适合灾备,配置导出适合人工审查和快速回滚。
监控和日常巡检
Nacos 不是装完就完了。注册中心和配置中心挂了,故障表现可能会绕到业务服务上,所以日常要有巡检。
先看端口:
ss -lntp | grep -E '8080|8848|9848|9849|7848'再看进程:
systemctl is-active nacos
jps -l | grep -i nacos再看磁盘:
df -h /opt/nacos /data/nacos
du -sh /data/nacos/logsPrometheus 抓取可以这样配:
scrape_configs:
- job_name: nacos
metrics_path: /nacos/actuator/prometheus
static_configs:
- targets:
- 10.0.0.11:8848
- 10.0.0.12:8848
- 10.0.0.13:8848访问后应该能看到指标:
curl -fsS http://10.0.0.11:8848/nacos/actuator/prometheus | head如果没有指标,先查 Nacos 版本和监控端点是否启用,再查认证和入口转发。
日常巡检一般看这些:
- 三个节点是不是都活着。
8848、9848、9849、7848是否通。- 数据库备份是否生成。
- 日志目录有没有暴涨。
- 配置变更记录有没有异常账号。
- 服务健康实例数量有没有突然下降。
- 控制台证书、域名、代理有没有过期风险。
Nacos 故障定位决策图
Nacos 出问题时,症状经常会伪装成“服务启动慢”“配置没刷新”“调用方找不到实例”。下面这张图适合值班排障时先走一遍,把控制台、API、鉴权、注册、配置、数据库和集群通信拆开验证。
这张图的使用顺序很重要:先证明入口和健康 API 正常,再看鉴权,再分注册链路、配置链路、外置库和集群通信。不要一看到“客户端连不上”就重启集群,重启会把原始故障现场冲掉。
常见故障一:启动失败
现象一般是:
systemctl start nacos 失败
容器反复重启
控制台打不开
logs/start.out 里有异常堆栈先查这几条:
java -version
systemctl status nacos --no-pager
journalctl -u nacos -n 200 --no-pager
tail -n 200 /opt/nacos/current/logs/start.out
tail -n 200 /opt/nacos/current/logs/nacos.log
ss -lntp | grep -E '8080|8848|9848|9849|7848'一般按这个顺序处理:
- Java 不对:Nacos 3.x 换 Java 17。
- 端口占用:找到占用进程或改端口。
- 内存不够:调小
JAVA_OPT_EXT或加内存。 - 鉴权参数缺失:补 token secret 和 identity。
- 数据库连不上:用
mysql和nc先测数据库。
修完后验证:
systemctl restart nacos
systemctl status nacos --no-pager
curl -i 'http://127.0.0.1:8848/nacos/v3/client/ns/instance/list?serviceName=quickstart.test.service'状态正常、API 有返回、控制台能打开,才算恢复。
常见故障二:集群节点异常
现象:
某台节点反复掉线
配置发布后部分节点读不到
服务实例列表在不同节点不一致
日志出现节点通信异常先看配置:
cat /opt/nacos/current/conf/cluster.conf
hostname -I
ip addr再测节点之间的端口:
for host in 10.0.0.11 10.0.0.12 10.0.0.13; do
nc -vz "$host" 8848
nc -vz "$host" 9848
nc -vz "$host" 9849
nc -vz "$host" 7848
done这里最常见的坑是 cluster.conf 写错 IP。比如写成了容器网段 IP、外网 IP、负载均衡 IP,节点之间当然互相找不到。
还要确认三台机器的鉴权配置一致:
grep -E "token.secret|server.identity" /opt/nacos/current/conf/application.properties如果只有某一台异常,把它从入口摘掉,修好后再加回去。不要让负载继续打到半残节点上。
常见故障三:配置发布成功但客户端没刷新
这个问题很常见。控制台显示发布成功,不代表业务代码已经用上新配置。
先查配置是否真的在 Nacos 里:
curl 'http://nacos-api.example.com:8848/nacos/v3/client/cs/config?namespaceId=prod-namespace-id&groupName=ORDER_GROUP&dataId=order-service.yaml'再查应用配置:
grep -R "nacos" -n application*.yml bootstrap*.yml再看应用日志:
grep -Ei "nacos|config|dataId|group|namespace|refresh|403|401|timeout" app.log常见原因就这几个:
- namespace 写的是名称,不是 ID。
- group 写错。
- dataId 后缀不一致。
- profile 规则没对上。
- 客户端账号没权限。
- gRPC 或长轮询被代理层影响。
- 业务 Bean 没有支持运行时刷新。
排这种问题,不要只盯控制台。要同时看 Nacos 查询结果、客户端日志和业务接口行为。
常见故障四:客户端连不上 Nacos
现象:
Client not connected
Connection refused
No server available
403 invalid token
unknown host
服务注册不上
配置拉取超时先在应用机器上测 DNS 和端口:
nslookup nacos-api.example.com
nc -vz nacos-api.example.com 8848
nc -vz nacos-api.example.com 9848再测 HTTP:
curl -i 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance/list?serviceName=quickstart.test.service'如果 8848 通但 9848 不通,服务注册和监听很可能会异常。很多 Nacos 2.x/3.x 客户端问题,最后都是只放了 8848,忘了 9848。
如果端口都通,再看应用日志:
grep -Ei "nacos|grpc|serverAddr|namespace|group|403|401|timeout|refused|unknown" app.log403 查账号密码和权限,unknown host 查 DNS,timeout 查网络和代理,Connection refused 查服务进程和端口监听。
常见故障五:服务下线后还有流量
服务下线不是拔电源。调用方通常有本地服务列表缓存,网关和连接池也可能短时间继续使用旧连接。
正确顺序是:
先把实例权重调低或下线
-> 等待一个刷新窗口
-> 看调用量下降
-> 停应用
-> 部署新版本
-> 健康检查通过
-> 恢复权重验证实例列表:
curl 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance/list?serviceName=order-service&groupName=ORDER_GROUP&namespaceId=prod-namespace-id'如果控制台已经下线,但仍有请求进来,就去看调用方日志和网关日志。Nacos 只负责服务发现,已经建立的连接和调用方缓存不一定立刻消失。
落地工程深水区
Nacos 的生产事故经常不是节点挂了,而是配置、注册中心、客户端缓存和数据库状态没有一起治理。部署完成后要把它当成“配置发布系统 + 服务发现系统”维护。
| 维度 | 运维落地点 | 验证方式 |
|---|---|---|
| 入口 | 官方建议集群前放内网 VIP 或域名,禁止把 Nacos 直接暴露到公网 | curl http://nacos-api.example.com:8848/nacos/actuator/health |
| 端口 | 8848、9848、9849、7848 按客户端、节点间通信和控制台分范围放行 | nc -vz nacos-1 9848 |
| 数据库 | 外置数据库备份、慢 SQL、连接池和恢复演练要独立管理 | 备份恢复后查询 config_info |
| 配置发布 | namespace、group、dataId、灰度、回滚和审批要有规范 | 控制台历史版本和发布记录 |
| 安全 | token、身份认证、控制台权限、默认账号清理和密钥轮换要进清单 | 登录审计和配置 diff |
一次真正可用的 Nacos 演练至少覆盖三条链路:
# 1. 服务端健康
curl -s http://nacos-api.example.com:8848/nacos/actuator/health
# 2. 配置读取
curl -s 'http://nacos-api.example.com:8848/nacos/v3/admin/cs/config?dataId=app.yaml&group=DEFAULT_GROUP&namespaceId=prod'
# 3. 服务发现
curl -s 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance/list?serviceName=order-service&groupName=ORDER_GROUP&namespaceId=prod'工程上最容易漏的是“谁能改配置”。建议把配置分成三层:
- 平台层:数据库、鉴权、日志、端口、集群通信,只允许运维改。
- 应用层:连接池、开关、限流阈值,由应用 owner 提交,运维执行或审批。
- 应急层:降级开关、灰度开关,有值班记录和自动回收时间。
生产上线检查清单
上线前按这个顺序过一遍:
- Nacos 版本确认,3.x 用 Java 17。
- 二进制包或镜像有校验和。
- 数据库初始化 SQL 和 Nacos 版本匹配。
- 三个节点
cluster.conf一致。 8848、9848、9849、7848端口按访问范围放行。- 控制台不暴露公网。
- 鉴权开启,secret 不用示例值。
- 应用账号和管理员账号分开。
- namespace/group/dataId 命名规范已经定好。
- 配置发布、查询、监听、回滚演练过。
- 数据库备份和恢复演练过。
- Prometheus 采集能看到指标。
- 日志目录有轮转策略。
- 离线包、镜像、脚本、SQL、校验和已经归档。
上线后至少验证这几条:
systemctl status nacos --no-pager
ss -lntp | grep -E '8080|8848|9848|9849|7848'
curl -i 'http://nacos-api.example.com:8848/nacos/v3/client/ns/instance/list?serviceName=quickstart.test.service'
curl -fsS 'http://10.0.0.11:8848/nacos/actuator/prometheus' | head再发布一条测试配置,查一次配置内容,启动一个测试服务注册一次。只有这三条链路都通,Nacos 才算真正可用。
