外观
Nacos:注册中心与配置中心
Nacos 单机跑起来很快,但生产必须用 MySQL 持久化 + 开鉴权 + 放通三个端口。这三点不配,重启丢配置、数据裸奔、集群连不上都会遇到。
一、单机部署
bash
cd /opt
wget https://github.com/alibaba/nacos/releases/download/2.3.2/nacos-server-2.3.2.tar.gz
tar xf nacos-server-2.3.2.tar.gz
ln -sfn /opt/nacos-server-2.3.2 /opt/nacos
java -versiontext
openjdk version "17.0.12" 2024-07-16Nacos 2.3 要求 JDK 8+,推荐 17。低于 8 无法启动。
默认是集群模式
直接 sh bin/startup.sh 会以 cluster 模式启动并寻找 cluster.conf,找不到就报错。单机必须加 -m standalone。
二、MySQL 持久化
默认使用内嵌 Derby,重启不丢但集群无法共享。生产必须换 MySQL。
bash
mysql -uroot -p -e "CREATE DATABASE nacos_config DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
mysql -uroot -p -e "CREATE USER 'nacos'@'10.0.0.%' IDENTIFIED BY 'NacosPass!2026';"
mysql -uroot -p -e "GRANT ALL ON nacos_config.* TO 'nacos'@'10.0.0.%';"
mysql -uroot -p nacos_config < /opt/nacos/conf/mysql-schema.sqlsql
-- 验证:应该有 12 张表
SHOW TABLES;text
+------------------------+
| Tables_in_nacos_config |
+------------------------+
| config_info |
| config_info_beta |
| config_tags_relation |
| group_capacity |
| his_config_info |
| permissions |
| roles |
| tenant_capacity |
| tenant_info |
| users |
+------------------------+三、application.properties
ini
# /opt/nacos/conf/application.properties
server.port=8848
server.servlet.contextPath=/nacos
# MySQL
spring.sql.init.platform=mysql
db.num=1
db.url.0=jdbc:mysql://10.0.0.32:3306/nacos_config?characterEncoding=utf8&connectTimeout=3000&socketTimeout=5000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
db.user.0=nacos
db.password.0=NacosPass!2026
# 鉴权(生产必须开)
nacos.core.auth.enabled=true
nacos.core.auth.system.type=nacos
nacos.core.auth.plugin.nacos.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkyMDI2VmVyeUxvbmdLZXk=
nacos.core.auth.server.identity.key=serverIdentity
nacos.core.auth.server.identity.value=NacosIdentity2026
# 关闭控制台的默认账号提示
nacos.core.auth.enable.userAgentAuthWhite=falsetoken.secret.key 必须是 Base64 编码、解码后 ≥ 32 字节:
bash
openssl rand -base64 48text
k3Jd8sLq2mNv7Xc1Yb5Za9Tf4Rw6Eu0Io3Pa8Sd2Fg5Hj7Kl1默认密钥等于没有鉴权
Nacos 的公开镜像自带示例密钥,不换的话任何人都能拿它伪造 token。nacos.core.auth.enabled=true 必须和自定义 token.secret.key 一起用。
四、启动
bash
cd /opt/nacos
sh bin/startup.sh -m standalone
tail -f logs/start.outtext
/usr/local/jdk-17/bin/java -Xms512m -Xmx512m -Xmn256m ... -Dnacos.standalone=true -jar /opt/nacos/target/nacos-server.jar
...
Nacos started successfully in stand alone mode. use external storageuse external storage 是 MySQL 生效的标志。如果显示 use embedded storage,说明数据库配置没读到。
bash
ss -lntp | grep -E '8848|9848|9849'text
LISTEN 0 128 *:8848 *:* users:(("java",pid=41200,fd=180))
LISTEN 0 128 *:9848 *:* users:(("java",pid=41200,fd=182))
LISTEN 0 128 *:9849 *:* users:(("java",pid=41200,fd=184))三个端口的作用:
| 端口 | 用途 |
|---|---|
8848 | HTTP / 控制台 / OpenAPI |
9848 | 客户端 gRPC(= 8848 + 1000) |
9849 | 集群内部 gRPC(= 8848 + 1001) |
7848 | 集群 Raft(仅集群模式) |
只开 8848 会导致客户端超时
Nacos 2.x 客户端默认走 gRPC 9848,不是 HTTP。只放通 8848 时,控制台能打开、注册能成功,但客户端长连接一直超时。
云安全组和系统防火墙都要放通 8848/9848/9849。
五、控制台
浏览器访问 http://10.0.0.31:8848/nacos,首次登录 nacos / nacos,立即改密码。
命令行验证:
bash
curl -s 'http://10.0.0.31:8848/nacos/v1/ns/instance/list?serviceName=order-api'json
{"name":"DEFAULT_GROUP@@order-api","groupName":"DEFAULT_GROUP","clusters":"","cacheMillis":10000,
"hosts":[{"instanceId":"10.0.0.41#8080#DEFAULT#DEFAULT_GROUP@@order-api","ip":"10.0.0.41","port":8080,
"weight":1.0,"healthy":true,"enabled":true,"ephemeral":true,"clusterName":"DEFAULT","serviceName":"DEFAULT_GROUP@@order-api"}],
"lastRefTime":1761570290314,"checksum":"","allIPs":false,"reachProtectionThreshold":false,"valid":true}登录取 token:
bash
curl -s -X POST 'http://10.0.0.31:8848/nacos/v1/auth/login' \
-d 'username=nacos&password=YourPass'json
{"accessToken":"eyJhbGciOiJIUzI1NiJ9...","tokenTtl":18000,"globalAdmin":true,"username":"nacos"}六、集群
ini
# /opt/nacos/conf/cluster.conf
10.0.0.31:8848
10.0.0.32:8848
10.0.0.33:8848三台的 cluster.conf 完全一样,且必须写 IP 不能写主机名(除非所有节点都能解析)。
bash
sh bin/startup.sh # 集群模式,不加 -m standalone验证:
bash
curl -s 'http://10.0.0.31:8848/nacos/v1/ns/operator/servers?accessToken=xxx'json
{"code":200,"servers":[{"ip":"10.0.0.31","servePort":8848,"state":"UP","lastRefTime":1761570300000,"address":"10.0.0.31:8848"},...]}客户端配置(Spring Cloud Alibaba):
yaml
spring:
cloud:
nacos:
discovery:
server-addr: 10.0.0.31:8848,10.0.0.32:8848,10.0.0.33:8848
namespace: prod
group: DEFAULT_GROUP
config:
server-addr: 10.0.0.31:8848,10.0.0.32:8848,10.0.0.33:8848
file-extension: yaml
namespace: prod客户端不要写 Nginx 代理地址
Nacos 2.x 的 gRPC 需要直连节点。用 Nginx 代理 8848 时,HTTP 请求能转发,但 gRPC 长连接建立不了。
要不客户端配置所有节点地址,要么用四层(TCP)负载均衡,且要支持 9848/9849。
七、命名空间与分组
| 概念 | 用途 |
|---|---|
| namespace | 环境隔离(dev/test/prod),ID 要填 UUID 不是名字 |
| group | 业务分组,默认 DEFAULT_GROUP |
| dataId | 配置文件名,如 order-api-prod.yaml |
bash
# 建命名空间
curl -X POST 'http://10.0.0.31:8848/nacos/v1/console/namespaces?accessToken=xxx' \
-d 'customNamespaceId=prod&namespaceName=prod&namespaceDesc=production'配置的 dataId 优先级(Spring Cloud Alibaba):
text
${prefix}-${spring.profiles.active}.${file-extension} > ${prefix}.${file-extension} > 共享配置八、常见故障
| 现象 | 原因 | 处置 |
|---|---|---|
启动报 No DataSource set | 数据库配置没读到 | 检查 spring.sql.init.platform 与 db.url.0 |
| 控制台能开,客户端注册失败 | 9848 未放通 | 开 8848/9848/9849 |
| 重启后配置没了 | 用的内嵌 Derby | 换 MySQL |
| 集群节点互相不认识 | cluster.conf 用了主机名、或 7848 未放通 | 改 IP,放通端口 |
invalid token | token.secret.key 太短或三台不一致 | 统一成 ≥32 字节的 Base64 |
| 内存持续上涨 | 配置太多 / 长轮询堆积 | 调堆、拆命名空间 |
| 控制台 403 | 鉴权开了但没登录 | 先 /v1/auth/login 拿 token |
九、踩过的坑
| 现象 | 根因 | 处置 |
|---|---|---|
| 单机不起 | 没加 -m standalone | 加参数 |
use embedded storage | 数据库配置未生效 | 检查配置项名(2.2+ 用 spring.sql.init.platform) |
改了 token.secret.key 后旧客户端全部鉴权失败 | 密钥变了 | 滚动重启客户端 |
| 同一个服务注册了两个 IP | 多网卡,注册了错误网卡 | 配 spring.cloud.nacos.discovery.ip |
| 配置改了不生效 | 没配 @RefreshScope 或没开自动刷新 | 加注解,或重启 |
| 集群只有一台能写 | Raft 未达多数派 | 恢复多数节点 |
| 客户端 15 秒超时 | gRPC 端口不通 | 放通 9848 |