Spring Cloud Alibaba 2025.0.0.0 配套搭建 Nacos 3.0.3

摘要

一、版本对照

1. Spring Cloud Alibaba 2025.0.x 适配关系

摘自官方 版本发布说明:

Spring Cloud Alibaba Version Spring Cloud Version Spring Boot Version
2025.0.0.0 2025.0.0 3.5.0

同页「组件版本关系」中,与 2025.0.0.0 对应的 Nacos 版本为:

Spring Cloud Alibaba Version Nacos Version
2025.0.0.0 3.0.3

对比:同属 2025.x 的 2025.1.0.0 适配 Spring Boot 4.0 / Spring Cloud 2025.1,组件为 Nacos 3.1.1。若走 Boot 4 路线请勿混用本文 Nacos 版本。

2. 环境准备

项目 要求说明
Nacos 3.0.3 官方要求 64 位 JDK 17+;建议机器至少 2C4G
MySQL(持久化 / 集群推荐) 5.6.5+(建议 8.0);集群生产强烈建议外置 MySQL,勿用嵌入式 Derby
Docker(可选) Docker 20+ / Docker Compose v2
集群节点 建议 ≥ 3 奇数台,防止脑裂

端口规划:

用途 端口 说明
Nacos 控制台 8080 Nacos 3.x 控制台入口
Nacos 主端口 8848 客户端注册 / 配置
客户端 gRPC 9848 客户端通信(主端口 +1000,需与 8848 一并放行)
服务端间 gRPC 9849 集群节点间通信(主端口 +1001)
Raft 7848 集群选主 / 一致性(主端口 -1000)

二、搭建 Nacos 3.0.3

官方文档:Nacos 快速开始、Docker 快速开始。

Nacos 3.x 相对 2.x 有几处常见差异,搭建前先记住:

  1. 控制台地址为 http://127.0.0.1:8080/index.html(不再是 http://ip:8848/nacos)。
  2. 控制台鉴权默认开启;启动前必须配置 JWT 密钥与服务端身份识别参数。
  3. 首次打开控制台需要初始化管理员用户 nacos 的密码(不再提供默认 nacos/nacos)。
  4. Spring Cloud Alibaba 2025.0.x 若使用 public / 空命名空间,需使用 Nacos Server 3.x,与本文版本一致。

1. 方式一:二进制包单机启动(推荐先理解流程)

(1)下载

1
2
3
4
5
6
7
8
9
10
# 任选其一
# 官网下载页:https://nacos.io/download/nacos-server/
wget https://download.nacos.io/nacos-server/nacos-server-3.0.3.zip
unzip nacos-server-3.0.3.zip

# GitHub Release:https://github.com/alibaba/nacos/releases/tag/3.0.3
wget https://github.com/alibaba/nacos/releases/download/3.0.3/nacos-server-3.0.3.tar.gz
tar -zxvf nacos-server-3.0.3.tar.gz

cd nacos

(2)生成鉴权相关配置

三个参数均无官方默认值,需自行生成并固定保存(集群节点必须一致):

配置项 / 环境变量 作用
nacos.core.auth.plugin.nacos.token.secret.key / NACOS_AUTH_TOKEN 签发 accessToken 的 JWT 密钥(Base64,原始长度建议 ≥ 32)
nacos.core.auth.server.identity.key / NACOS_AUTH_IDENTITY_KEY 服务端身份识别 Key
nacos.core.auth.server.identity.value / NACOS_AUTH_IDENTITY_VALUE 服务端身份识别 Value

示例生成方式:

1
2
3
4
5
6
7
8
9
10
11
# JWT 密钥:先生成 ≥32 字符明文,再 Base64
openssl rand -base64 32
# 3kphyB8N/h/7NHvoXdvM7hwfCsnpBXK+1nlruWb2gUQ=
openssl rand -base64 48
# PZhCxx3Rj5Z3GZ59tBkxSElxHCKPMTEtInHiJSVqUnz435/H2iwY3buSEX0DFQ6j

# identity key / value 可用任意自定义字符串,例如:
echo -n 'nacos_identity_key' | base64
# bmFjb3NfaWRlbnRpdHlfa2V5
echo -n 'nacos_identity_value' | base64
# bmFjb3NfaWRlbnRpdHlfdmFsdWU=

也可在首次执行 startup.sh -m standalone 时按提示交互填入,
填入后会写入 conf/application.properties。
但建议直接修改配置文件,因为 base64 生成的编码可能含有特殊字符导致配置失败。

手动写入示例(请替换为你自己的值):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
### conf/application.properties 片段
# 使用“内置的 Nacos 原生鉴权体系”,默认 nacos,还支持 ldap
nacos.core.auth.system.type=nacos


# 总开关,是否开启 Nacos 服务端 API 的鉴权系统,默认为 false(当前值):表示关闭鉴权。
# 此时任何人无需用户名密码即可通过 Open API 访问、修改 Nacos 上的配置和服务列表。这在生产环境是极不安全的。
nacos.core.auth.enabled=true
# 是否开启 Nacos 管理 API 的鉴权,默认为true
nacos.core.auth.admin.enabled=true
# 是否开启 Nacos 控制台(Web UI)的鉴权,默认为true
nacos.core.auth.console.enabled=true


# 用于识别请求来源的身份键值对(白名单机制)
# 当 nacos.core.auth.enabled=true 时生效
# 如果请求的 Header 中包含 key=nacos_identity_key 且 value=nacos_identity_value,Nacos 会认为这是一个受信任的内部服务器请求(例如通过 Nginx 代理转发的请求,或者 Nacos 集群节点间的通信),从而跳过常规的用户 Token 鉴权。
# 在生产环境中,必须修改这两个默认值,防止被恶意利用绕过鉴权。
nacos.core.auth.server.identity.key=替换为你的identityKey
nacos.core.auth.server.identity.value=替换为你的identityValue


# 用于生成 Token 的密钥(Base64 编码的字符串)
# Nacos 使用 JWT (JSON Web Token) 机制,该密钥用于签名和验证 Token。
# 在生产环境中,必须将其设置为一个复杂的、唯一的 Base64 字符串,并确保所有 Nacos 节点使用相同的密钥(集群模式下)
nacos.core.auth.plugin.nacos.token.secret.key=替换为你的Base64密钥

(3)修改端口(可选)

Nacos 3.x 已把 Server API 与 控制台 拆成两个独立 HTTP 端口。改端口时请使用下面专用配置,不要再写 server.port(它是 Spring Boot 全局 HTTP 端口,容易让 Server 与控制台抢同一端口而启动失败)。参见 系统参数。

配置项 默认值 说明
nacos.server.main.port 8848 Server 主端口(HTTP OpenAPI / Admin)
nacos.console.port 8080 控制台端口
gRPC 主端口 + 1000 9848 客户端 gRPC(随主端口偏移,不能单独随意指定)
gRPC 主端口 + 1001 9849 服务端间 gRPC
Raft 主端口 - 1000 7848 集群 Raft(单机可忽略)

conf/application.properties 示例(把主端口改成 8849、控制台改成 8081):

1
2
nacos.server.main.port=8849
nacos.console.port=8081

改完后实际端口变为:

用途 新端口
控制台 8081 → http://127.0.0.1:8081/index.html
Server 主端口 8849
客户端 gRPC 9849(8849 + 1000)

客户端 spring.cloud.nacos.server-addr 只填主端口即可,例如 127.0.0.1:8849;gRPC 端口由客户端按同样偏移规则自动推算。

防火墙 / 安全组至少放行:控制台端口、主端口、客户端 gRPC(主端口+1000)。

(4)启动 / 停止

1
2
3
4
5
6
7
8
9
10
11
# Linux / macOS 单机模式
sh bin/startup.sh -m standalone
# Ubuntu 若 [[ 报错,改用:
# bash bin/startup.sh -m standalone

# 指定jdk环境,也可以将 JAVA_HOME 添加到 bin/startup.sh 中
JAVA_HOME=/usr/local/jvm/jdk17 \
sh bin/startup.sh -m standalone

# 查看启动日志
tail -f logs/start.out

看到类似日志表示成功:

1
Nacos started successfully in stand alone mode. use embedded storage

停止:

1
sh bin/shutdown.sh

(5)验证

  1. 浏览器打开:http://127.0.0.1:8080/index.html(若改过控制台端口则替换),按提示初始化 nacos 管理员密码。

  2. 或用 API 首次初始化管理员密码(密码为空则会随机生成,务必保存):

1
2
curl -X POST 'http://127.0.0.1:8848/nacos/v3/auth/user/admin' \
-d 'password=YourStrongPassword'

该接口只能在尚未创建管理员用户时调用一次。成功后再次调用会返回类似:

1
{"code":409,"message":"have admin user cannot use it.","data":null}

说明管理员 nacos 已存在,此时应改用登录接口拿 accessToken,而不是继续调 /admin:

1
2
3
curl -s -X POST 'http://127.0.0.1:8848/nacos/v3/auth/user/login' \
-d 'username=nacos' \
-d 'password=当初初始化时设置的密码'
  1. 服务注册 / 发现快速探测(v3 Client API)。

若已开启客户端鉴权(nacos.core.auth.enabled=true,报 401 User not found / 403 Forbidden 时就是这种情况),须先登录拿 accessToken:

1
2
3
4
5
6
7
8
9
10
11
12
# 登录(密码为你初始化的 nacos 管理员密码)
TOKEN=$(curl -s -X POST 'http://127.0.0.1:8848/nacos/v3/auth/user/login' \
-d 'username=nacos' \
-d 'password=YourStrongPassword' | sed -n 's/.*"accessToken":"\([^"]*\)".*/\1/p')

echo "TOKEN=$TOKEN"

# 注册(Header 或 query 携带 accessToken 均可)
curl -X POST "http://127.0.0.1:8848/nacos/v3/client/ns/instance?serviceName=quickstart.test.service&ip=127.0.0.1&port=8080&accessToken=${TOKEN}"

# 发现
curl -X GET "http://127.0.0.1:8848/nacos/v3/client/ns/instance/list?serviceName=quickstart.test.service&accessToken=${TOKEN}"

未开启客户端鉴权时,可省略登录,直接调用无 accessToken 的 URL(官方快速开始示例即为此种情况)。

2. 方式二:Docker 单机(嵌入式 Derby)

官方镜像:nacos/nacos-server:v3.0.3。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export NACOS_AUTH_TOKEN="$(openssl rand -base64 48)"
export NACOS_AUTH_IDENTITY_KEY="nacos_identity_key"
export NACOS_AUTH_IDENTITY_VALUE="nacos_identity_value"

docker pull nacos/nacos-server:v3.0.3

docker run -d \
--name nacos-standalone \
-e MODE=standalone \
-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}" \
-e JVM_XMS=512m \
-e JVM_XMX=512m \
-p 8080:8080 \
-p 8848:8848 \
-p 9848:9848 \
nacos/nacos-server:v3.0.3

若要改容器内端口,使用镜像环境变量(对应配置见上一节):

环境变量 对应配置 默认
NACOS_APPLICATION_PORT nacos.server.main.port 8848
NACOS_CONSOLE_PORT nacos.console.port 8080

示例:主端口 8849、控制台 8081(gRPC 随之变为 9849,映射要一起改):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker run -d \
--name nacos-standalone \
-e MODE=standalone \
-e NACOS_APPLICATION_PORT=8849 \
-e NACOS_CONSOLE_PORT=8081 \
-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}" \
-e JVM_XMS=512m \
-e JVM_XMX=512m \
-p 8081:8081 \
-p 8849:8849 \
-p 9849:9849 \
nacos/nacos-server:v3.0.3

查看日志:

1
docker logs -f nacos-standalone

出现 Nacos started successfully ... 后,访问 http://127.0.0.1:8080/index.html 初始化管理员密码。

% note info %
低配机器务必限制 JVM,否则容易 OOM / 卡死。生产请改用外置 MySQL,详见下文「三、MySQL 持久化」。

% endnote %

3. Docker Compose 最小示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# docker-compose-nacos.yml
services:
nacos:
image: nacos/nacos-server:v3.0.3
container_name: nacos
environment:
MODE: standalone
# 如需改端口,取消注释并同步改 ports 映射与 gRPC(主端口+1000)
# NACOS_APPLICATION_PORT: 8849
# NACOS_CONSOLE_PORT: 8081
NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN}
NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY}
NACOS_AUTH_IDENTITY_VALUE: ${NACOS_AUTH_IDENTITY_VALUE}
JVM_XMS: 512m
JVM_XMX: 512m
TZ: Asia/Shanghai
ports:
- "8080:8080"
- "8848:8848"
- "9848:9848"
restart: unless-stopped
1
2
3
4
5
export NACOS_AUTH_TOKEN="$(openssl rand -base64 32)"
export NACOS_AUTH_IDENTITY_KEY="nacos_identity_key"
export NACOS_AUTH_IDENTITY_VALUE="nacos_identity_value"

docker compose -f docker-compose-nacos.yml up -d

三、MySQL 持久化

单机快速体验可用嵌入式 Derby;配置中心数据、用户权限等需要跨重启保活,或后续要做集群时,必须切换外置 MySQL。官方部署说明:单机模式部署、集群模式部署。

1. 准备数据库

  1. MySQL 5.6.5+(建议 8.0),字符集建议 utf8mb4。

  2. 创建库与账号(密码请自行替换):

1
2
3
4
5
CREATE DATABASE nacos DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE USER 'nacos'@'%' IDENTIFIED BY 'Nacos_Db_Passw0rd';
GRANT ALL PRIVILEGES ON nacos.* TO 'nacos'@'%';
FLUSH PRIVILEGES;
  1. 导入官方表结构(发行包内 conf/mysql-schema.sql,或从 Nacos 源码 conf 下载同版本脚本):

1
2
# 在 nacos 解压目录执行
mysql -h127.0.0.1 -P3306 -unacos -p nacos < conf/mysql-schema.sql

请使用与 Nacos 3.0.3 同版本的 mysql-schema.sql,勿混用 2.x 脚本。初始化只需执行一次;多节点集群共享同一库。

2. 二进制包:改配置后单机启动

编辑 conf/application.properties,取消 / 补充 MySQL 相关项(示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
### 使用 MySQL 数据源(与 3.0.3 发行包 conf/application.properties 一致)
spring.sql.init.platform=mysql

db.num=1
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
db.user=nacos
db.password=Nacos_Db_Passw0rd

### 鉴权(与第二节一致,必须已配置)
nacos.core.auth.enabled=true
nacos.core.auth.system.type=nacos
nacos.core.auth.plugin.nacos.token.secret.key=替换为你的Base64密钥
nacos.core.auth.server.identity.key=替换为你的identityKey
nacos.core.auth.server.identity.value=替换为你的identityValue

启动方式与单机 Derby 相同:

1
sh bin/startup.sh -m standalone

成功时日志类似:

1
Nacos started successfully in stand alone mode. use external storage

对比 Derby 时的 use embedded storage,若仍显示 embedded,说明 MySQL 配置未生效。

3. Docker:单机 + 外置 / Compose 内置 MySQL

(1)连接已有 MySQL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
docker run -d \
--name nacos-standalone-mysql \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=192.168.1.10 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_DB_NAME=nacos \
-e MYSQL_SERVICE_USER=nacos \
-e MYSQL_SERVICE_PASSWORD=Nacos_Db_Passw0rd \
-e MYSQL_SERVICE_DB_PARAM='characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=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}" \
-e JVM_XMS=512m \
-e JVM_XMX=512m \
-p 8080:8080 \
-p 8848:8848 \
-p 9848:9848 \
nacos/nacos-server:v3.0.3
环境变量 说明
SPRING_DATASOURCE_PLATFORM 设为 mysql 启用外置库
MYSQL_SERVICE_HOST / PORT / DB_NAME 库地址
MYSQL_SERVICE_USER / PASSWORD 账号密码(勿含逗号 ,)
MYSQL_SERVICE_DB_PARAM JDBC 附加参数

容器启动前请已在目标库执行过 mysql-schema.sql。

(2)Docker Compose 一键(Nacos + MySQL)

也可直接参考 nacos-docker 的 example/standalone-mysql.yaml(版本在 .env 固定为 v3.0.3,并先跑 mysql-init.sh 准备初始化脚本)。自写最小示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# docker-compose-nacos-mysql.yml
services:
mysql:
image: mysql:8.0.30
container_name: nacos-mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: nacos
MYSQL_USER: nacos
MYSQL_PASSWORD: Nacos_Db_Passw0rd
TZ: Asia/Shanghai
volumes:
# 将 mysql-schema.sql 放到 ./mysql-init/ 下,首次启动自动导入
- ./mysql-init:/docker-entrypoint-initdb.d
- nacos-mysql-data:/var/lib/mysql
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
ports:
- "3306:3306"
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 10s
retries: 10
restart: unless-stopped

nacos:
image: nacos/nacos-server:v3.0.3
container_name: nacos
depends_on:
mysql:
condition: service_healthy
environment:
MODE: standalone
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql
MYSQL_SERVICE_PORT: 3306
MYSQL_SERVICE_DB_NAME: nacos
MYSQL_SERVICE_USER: nacos
MYSQL_SERVICE_PASSWORD: Nacos_Db_Passw0rd
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN}
NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY}
NACOS_AUTH_IDENTITY_VALUE: ${NACOS_AUTH_IDENTITY_VALUE}
JVM_XMS: 512m
JVM_XMX: 512m
TZ: Asia/Shanghai
ports:
- "8080:8080"
- "8848:8848"
- "9848:9848"
restart: unless-stopped

volumes:
nacos-mysql-data:
1
2
3
4
5
6
7
8
9
mkdir -p mysql-init
# 从发行包拷贝同版本脚本
cp /path/to/nacos/conf/mysql-schema.sql mysql-init/

export NACOS_AUTH_TOKEN="$(openssl rand -base64 32)"
export NACOS_AUTH_IDENTITY_KEY="nacos_identity_key"
export NACOS_AUTH_IDENTITY_VALUE="nacos_identity_value"

docker compose -f docker-compose-nacos-mysql.yml up -d

常见问题:

  1. Public Key Retrieval is not allowed:JDBC URL / MYSQL_SERVICE_DB_PARAM 追加 allowPublicKeyRetrieval=true。

  2. db.num is null / 连不上库:确认 spring.sql.init.platform=mysql(或环境变量 SPRING_DATASOURCE_PLATFORM=mysql)及 db.* 完整。

  3. 重启后数据仍丢:可能仍跑在 Derby,或 MySQL volume 未挂载成功。


四、集群搭建

生产推荐:≥ 3 个 Nacos 节点 + 外置 MySQL(建议高可用)+ 域名 / 内网 SLB 对外暴露主端口与客户端 gRPC。直连任意单节点 IP 也可工作,但节点故障后客户端需改配置,运维成本更高。架构说明见 集群模式部署。

集群模式下:

  1. 必须共享同一套外置 MySQL(嵌入式 Derby 虽可用 -p embedded 靠 Raft 组逻辑集群,排障成本高,官方不推荐生产)。
  2. 所有节点的 鉴权三件套必须完全一致(token.secret.key / identity.key / identity.value)。
  3. 节点间需放行:主端口、客户端 gRPC(+1000)、服务端 gRPC(+1001)、Raft(-1000)。
  4. 启动命令不要再带 -m standalone。

1. 二进制包三节点示例

假设三台机器(或同机不同端口,演示时可改;生产请每机一进程):

节点 IP 主端口
nacos-1 192.168.1.11 8848
nacos-2 192.168.1.12 8848
nacos-3 192.168.1.13 8848

(1)各节点统一 application.properties

在上一节 MySQL 配置基础上,保证三台鉴权参数相同,并按需指定本机地址(多网卡时尤其重要):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
### 多网卡时可固定对外 IP,避免注册成错误网卡
# nacos.inetutils.ip-address=192.168.1.11

spring.sql.init.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.1.10:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
db.user=nacos
db.password=Nacos_Db_Passw0rd

nacos.core.auth.enabled=true
nacos.core.auth.console.enabled=true
nacos.core.auth.system.type=nacos
nacos.core.auth.plugin.nacos.token.secret.key=替换为你的Base64密钥
nacos.core.auth.server.identity.key=替换为你的identityKey
nacos.core.auth.server.identity.value=替换为你的identityValue

(2)各节点相同的 conf/cluster.conf

三台机器内容一致,每行 ip:主端口:

1
2
3
4
# conf/cluster.conf
192.168.1.11:8848
192.168.1.12:8848
192.168.1.13:8848

(3)启动与验证

每台分别执行(集群模式,无 -m standalone):

1
2
sh bin/startup.sh
# Ubuntu:bash bin/startup.sh

成功日志类似:

1
Nacos started successfully in cluster mode. use external storage

任选一台控制台(或经 SLB)打开:http://任意节点控制台端口/index.html。管理员密码只需初始化一次(数据在 MySQL)。

控制台「集群管理」应能看到 3 个节点;也可用健康检查 / 成员列表 API(需先登录拿 token,方式同第二节)。

客户端 server-addr 可填:

1
2
3
4
5
6
7
spring:
cloud:
nacos:
# 推荐:VIP / 域名(内网 SLB 同时转发 8848 与 9848)
server-addr: nacos.example.internal:8848
# 或直连多地址(逗号分隔)
# server-addr: 192.168.1.11:8848,192.168.1.12:8848,192.168.1.13:8848

% note tip %
若前面挂了四层负载或 Nginx,8848 与 9848 都要转发且保持「主端口 +1000 = gRPC」的偏移。只转 8848、不转 gRPC,或把 gRPC 配成 HTTP/HTTP2,会出现注册失败或频繁超时。完整示例见下文「Nginx 反向代理」。

% endnote %

2. Docker Compose 集群示例(hostname 模式)

官方示例:nacos-docker example/cluster-hostname.yaml。核心环境变量:

环境变量 示例 说明
MODE cluster(镜像默认) 集群模式
PREFER_HOST_MODE hostname 节点互相用 hostname 发现
NACOS_SERVERS nacos1:8848 nacos2:8848 nacos3:8848 空格分隔的成员列表
SPRING_DATASOURCE_PLATFORM mysql 外置库
NACOS_AUTH_* 与单机相同 三节点必须相同

自写精简示例如下(生产请将 MySQL 换为外部高可用库,并收紧密码):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# docker-compose-nacos-cluster.yml
services:
mysql:
image: mysql:8.0.30
container_name: nacos-mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: nacos
MYSQL_USER: nacos
MYSQL_PASSWORD: Nacos_Db_Passw0rd
volumes:
- ./mysql-init:/docker-entrypoint-initdb.d
- nacos-mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 10s
retries: 10
restart: unless-stopped

nacos1: &nacos-node
image: nacos/nacos-server:v3.0.3
hostname: nacos1
container_name: nacos1
depends_on:
mysql:
condition: service_healthy
environment:
PREFER_HOST_MODE: hostname
NACOS_SERVERS: nacos1:8848 nacos2:8848 nacos3:8848
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql
MYSQL_SERVICE_PORT: 3306
MYSQL_SERVICE_DB_NAME: nacos
MYSQL_SERVICE_USER: nacos
MYSQL_SERVICE_PASSWORD: Nacos_Db_Passw0rd
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
NACOS_AUTH_TOKEN: ${NACOS_AUTH_TOKEN}
NACOS_AUTH_IDENTITY_KEY: ${NACOS_AUTH_IDENTITY_KEY}
NACOS_AUTH_IDENTITY_VALUE: ${NACOS_AUTH_IDENTITY_VALUE}
JVM_XMS: 512m
JVM_XMX: 512m
TZ: Asia/Shanghai
ports:
- "8080:8080"
- "8848:8848"
- "9848:9848"
restart: unless-stopped

nacos2:
<<: *nacos-node
hostname: nacos2
container_name: nacos2
ports:
- "8081:8080"
- "8849:8848"
- "9849:9848"

nacos3:
<<: *nacos-node
hostname: nacos3
container_name: nacos3
ports:
- "8082:8080"
- "8850:8848"
- "9850:9848"

volumes:
nacos-mysql-data:
1
2
3
4
5
6
7
8
9
mkdir -p mysql-init
cp /path/to/nacos/conf/mysql-schema.sql mysql-init/

export NACOS_AUTH_TOKEN="$(openssl rand -base64 32)"
export NACOS_AUTH_IDENTITY_KEY="nacos_identity_key"
export NACOS_AUTH_IDENTITY_VALUE="nacos_identity_value"

docker compose -f docker-compose-nacos-cluster.yml up -d
docker compose -f docker-compose-nacos-cluster.yml logs -f nacos1

本机快速验证时,应用可临时连 127.0.0.1:8848(或逗号列出 8848,8849,8850)。真实环境仍建议用域名 / SLB / Nginx 统一入口。

3. Nginx 反向代理示例

官方说明:部署架构概览、Nginx 负载均衡指南。

对外建议暴露:

对外端口 协议 后端 说明
8848 HTTP 各节点 8848 OpenAPI / 鉴权 login 等
9848 TCP(stream) 各节点 9848 客户端 gRPC 长连接(= 8848 + 1000)
8080 HTTP 各节点 8080 Nacos 3.x 控制台

不要把 gRPC 配成 http / http2 反代,否则连接会被掐断,表现为服务反复上下线。节点间端口 9849、7848 仅内网互通,勿对公网开放。

先确认 Nginx 带 stream 模块:

1
2
nginx -V 2>&1 | tr ' ' '\n' | grep -E 'stream'
# 应能看到 --with-stream

(1)推荐:保持默认端口偏移(客户端无感)

server-addr 填 nacos.example.com:8848 时,客户端会自动连 nacos.example.com:9848,因此 Nginx 对外监听端口也必须满足同一偏移:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# /etc/nginx/nginx.conf 片段(stream 必须与 http 同级,不能写在 http {} 里)

worker_processes auto;

events {
worker_connections 10240;
}

# ---------- gRPC:四层 TCP 反代 ----------
stream {
upstream nacos_grpc {
# 可选:按客户端 IP 粘滞,减少长连接漂移
hash $remote_addr consistent;
server 192.168.1.11:9848 max_fails=3 fail_timeout=30s;
server 192.168.1.12:9848 max_fails=3 fail_timeout=30s;
server 192.168.1.13:9848 max_fails=3 fail_timeout=30s;
}

server {
listen 9848;
proxy_pass nacos_grpc;
proxy_connect_timeout 10s;
# gRPC 长连接,超时宜设大一些
proxy_timeout 300s;
proxy_next_upstream on;
}
}

# ---------- HTTP:API + 控制台 ----------
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 配置内容可能较大
client_max_body_size 20m;

upstream nacos_api {
server 192.168.1.11:8848 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8848 max_fails=3 fail_timeout=30s;
server 192.168.1.13:8848 max_fails=3 fail_timeout=30s;
}

upstream nacos_console {
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.13:8080 max_fails=3 fail_timeout=30s;
}

# 客户端 / OpenAPI:http://nacos.example.com:8848
server {
listen 8848;
server_name nacos.example.com;

location / {
proxy_pass http://nacos_api;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
}

# 可选:简单探活
location = /nacos/v3/console/health/readiness {
proxy_pass http://nacos_api;
access_log off;
}
}

# 控制台:http://nacos-console.example.com:8080/index.html
server {
listen 8080;
server_name nacos-console.example.com;

location / {
proxy_pass http://nacos_console;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 控制台前端资源 / 接口
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
}
}
}

检查并热加载:

1
nginx -t && nginx -s reload

应用侧只填 Nginx 入口:

1
2
3
4
5
6
spring:
cloud:
nacos:
server-addr: nacos.example.com:8848
username: nacos
password: YourStrongPassword

浏览器访问控制台:http://nacos-console.example.com:8080/index.html。

(2)自定义对外端口时:仍须保持 +1000 偏移

若希望对外用 7847(HTTP)而不想占用 8848,则 gRPC 必须对外监听 8847(= 7847 + 1000),客户端才能算出正确端口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
stream {
upstream nacos_grpc {
server 192.168.1.11:9848;
server 192.168.1.12:9848;
server 192.168.1.13:9848;
}
server {
listen 8847; # = 对外主端口 + 1000
proxy_pass nacos_grpc;
proxy_timeout 300s;
}
}

http {
upstream nacos_api {
server 192.168.1.11:8848;
server 192.168.1.12:8848;
server 192.168.1.13:8848;
}
upstream nacos_console {
server 192.168.1.11:8080;
server 192.168.1.12:8080;
server 192.168.1.13:8080;
}

# 对外主端口 7847:可同时按路径拆 API 与控制台(官方指南同思路)
server {
listen 7847;
server_name nacos.example.com;

location /nacos/ {
proxy_pass http://nacos_api/nacos/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# Nacos 3.x 控制台路径无 /nacos 前缀
location / {
proxy_pass http://nacos_console;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}

此时客户端:

1
spring.cloud.nacos.server-addr: nacos.example.com:7847

控制台:http://nacos.example.com:7847/index.html。

(3)HTTPS 控制台(可选)

仅给控制台上证书即可;客户端注册发现一般仍走内网明文 8848/9848。证书终止在 Nginx,后端继续 http://nacos_console。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 443 ssl http2;
server_name nacos-console.example.com;

ssl_certificate /etc/nginx/certs/nacos-console.crt;
ssl_certificate_key /etc/nginx/certs/nacos-console.key;

location / {
proxy_pass http://nacos_console;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}

(4)Nginx 相关注意点

  1. stream 与 http 同级:写在 http {} 内会直接报错。

  2. 偏移不能破:对外 主端口 与 主端口+1000 必须成对出现。

  3. 单机也可用同一套配置:upstream 里只留一个 server 即可。

  4. 扩容:新增节点后改 Nginx upstream 再 nginx -s reload,应用无需改 server-addr。

  5. 安全:生产尽量内网暴露 8848/9848;控制台可单独域名 + HTTPS + IP 白名单。

4. 集群常见问题

  1. 节点无法互相发现:检查 cluster.conf / NACOS_SERVERS 是否互通;防火墙是否放行 8848/9848/9849/7848。

  2. 鉴权不一致导致节点异常:三件套任一不一致都会出问题,务必三台拷贝同一份配置。

  3. 多网卡注册成内网错误 IP:设置 nacos.inetutils.ip-address 或 Docker 的 NACOS_SERVER_IP。

  4. 只用 2 节点:偶数节点在半数故障时易无法选主,生产请用奇数台(≥3)。

  5. Nginx 后客户端连不上 / 反复掉线:检查是否遗漏 9848 的 stream TCP 转发,或误用了 HTTP2;对外端口是否满足「主端口 +1000」。


五、应用侧快速接入(SCA 2025.0.0.0)

官方指南:SCA · Nacos 快速开始。

1. BOM 与依赖

父 POM / 依赖管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.5.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2025.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2025.0.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

业务模块按需引入(版本由 BOM 管理):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- 注册发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- 配置中心 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- 服务间调用负载均衡(消费端常用) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

Starter 会传递依赖 nacos-client:3.0.3,与上文服务端版本对齐。

2. application.yml 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server:
port: 18082

spring:
application:
name: demo-provider
config:
import:
- optional:nacos:demo-provider.properties?refreshEnabled=true
cloud:
nacos:
server-addr: 127.0.0.1:8848
username: nacos
password: YourStrongPassword
discovery:
server-addr: ${spring.cloud.nacos.server-addr}
config:
server-addr: ${spring.cloud.nacos.server-addr}
file-extension: properties

% note tip %
2025.0.x 起建议统一使用 spring.config.import 拉取 Nacos 配置;shared-configs / extension-configs 等旧方式已废弃。更靠后的 2025.1.x 会正式废弃 Bootstrap,接入时直接写在 application.yml 即可。

% endnote %

3. 代码最小示例

1
2
3
4
5
6
7
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}

六、联调检查清单

检查项 预期结果
Nacos 进程 / 容器 单机:stand alone;集群:cluster mode;外置库:use external storage
Nacos 控制台 http://127.0.0.1:8080/index.html(或 Nginx / 域名)可登录
MySQL config_info 等表有数据;重启 Nacos 后配置不丢
集群节点 控制台「集群管理」可见全部节点且状态正常
8848 / 9848(及集群 9849 / 7848) 防火墙或安全组已放行
Nginx 反代 8848 HTTP + 9848 TCP(stream)成对;nginx -V 含 --with-stream
应用注册 Nacos「服务管理」可见实例,且 healthy
客户端版本 nacos-client 3.0.3(由 SCA BOM 引入)

常见问题:

  1. 应用连不上 Nacos:除了 8848,还必须打通 9848(gRPC);经 Nginx / SLB 时两条链路都要转,且保持主端口 +1000 偏移。

  2. 控制台 404 / 打不开:Nacos 3.x 用 8080,不要再用 8848/nacos。

  3. 外网 IP 打不开控制台:本机 curl 正常且监听 *:8080 时,多半是云安全组未放行控制台端口;与 nacos.inetutils.ip-address 无关。

  4. 重启后配置丢失:仍在用 Derby,或未导入 / 未指向 MySQL。

  5. 集群某节点起不来:核对 cluster.conf、鉴权三件套一致性、数据库连通性。

  6. 经 Nginx 后服务反复上下线:常因 gRPC 用了 HTTP/HTTP2 反代;应改为 stream TCP,并把 proxy_timeout 调大。

  7. 版本混用:按 SCA 官方矩阵固定 Nacos 3.0.3 最省事。


七、参考链接