Nacos 集群部署与生产最佳实践
单机 Nacos 只能演示。生产环境需要:多节点集群、外置 MySQL、安全加固、监控告警。本文给出完整部署与运维方案。
集群部署
部署架构
┌──────────────────────────────────┐
│ Nacos Cluster │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │ ← 3 节点,同网段
│ └───┬────┘ └───┬────┘ └───┬────┘ │
└──────┼──────────┼──────────┼─────┘
│ │ │
┌────▼──────────▼──────────▼────┐
│ MySQL(主从 + 备份) │ ← 共享存储
└────────────────────────────────┘
▲
┌─────────────┴─────────────┐
│ LB(域名/nginx/slb) │ ← 客户端统一入口
└───────────────────────────┘关键要求
| 项 | 要求 |
|---|---|
| 节点数 | ≥3(奇数,选举/多数派需要) |
| 存储 | 外置 MySQL(生产禁止内嵌 Derby) |
| 时钟 | 节点间 NTP 同步(心跳超时判定依赖时间) |
| 网络 | 节点间内网互通,延迟低 |
| 版本 | 集群节点同版本,避免协议不兼容 |
部署步骤
- 准备 MySQL:建库建表(
nacos_config.sql脚本初始化) - 配置
application.properties:
properties
# 数据源
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://mysql-host:3306/nacos_config?characterEncoding=utf8&serverTimezone=Asia/Shanghai
db.user.0=nacos
db.password.0=your-password- 配置
cluster.conf:每节点一行,列出集群所有节点
192.168.1.10:8848
192.168.1.11:8848
192.168.1.12:8848- 启动:三节点依次启动
bash
sh startup.sh -m cluster- 验证:访问任一节点控制台,
/nacos/v1/ns/operator/metrics查看节点数
Docker Compose 示例
yaml
version: '3'
services:
nacos1:
image: nacos/nacos-server:v2.3.2
container_name: nacos1
environment:
MODE: cluster
NACOS_SERVERS: "nacos1:8848,nacos2:8848,nacos3:8848"
SPRING_DATASOURCE_PLATFORM: mysql
MYSQL_SERVICE_HOST: mysql
MYSQL_SERVICE_DB_NAME: nacos_config
MYSQL_SERVICE_USER: nacos
MYSQL_SERVICE_PASSWORD: secret
ports:
- "8848:8848"
- "9848:9848" # gRPC 端口
nacos2: { ... }
nacos3: { ... }
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: nacos_config
volumes:
- ./nacos-mysql.sql:/docker-entrypoint-initdb.d/nacos.sql端口说明
| 端口 | 用途 |
|---|---|
| 8848 | HTTP / 控制台 / OpenAPI |
| 9848 | 客户端 gRPC(8848+1000) |
| 9849 | 服务间 gRPC(8848+1001) |
| 7848 | JRaft 通信(8848-1000) |
防火墙/安全组需放通上述端口。
持久化 MySQL
为什么必须外置
- 内嵌 Derby:单机存储,集群节点间不共享,数据互相独立(生产禁用)
- 外置 MySQL:所有节点读写同一库,配置/持久实例全局一致
MySQL 高可用
Nacos 节点 ──▶ MySQL 主库(写)
│ 主从复制(binlog)
▼
MySQL 从库(读/容灾)
│
▼
备份(每日全量 + binlog)表说明
| 表 | 作用 |
|---|---|
| config_info | 配置内容(含 md5、content) |
| config_info_gray | 灰度配置 |
| config_info_beta | Beta 配置 |
| his_config_info | 配置历史(版本回溯) |
| users / roles / permissions | 用户与权限(认证) |
注意事项
- MySQL 字符集 UTF-8(避免中文配置乱码)
- 定期清理
his_config_info历史表(避免无限膨胀) - 主从延迟会影响配置读取(读主库可规避)
集群间数据同步
同步机制回顾
| 数据 | 同步方式 |
|---|---|
| 临时实例 | Distro:节点间异步同步 + 反熵 |
| 持久实例 / 配置 | JRaft:Leader 写入,日志复制到多数派 |
| 心跳状态 | 各节点独立维护,Distro 同步 |
集群扩缩容
扩容:
1. 新节点加入 cluster.conf
2. 启动后自动感知集群
3. JRaft/Distro 数据自动补齐
4. 逐步接入流量
缩容:
1. 先从负载均衡摘除节点
2. 确认无客户端连接
3. 移出 cluster.conf 并下线安全认证
开启认证
properties
# application.properties
nacos.core.auth.enabled=true
nacos.core.auth.plugin.nacos.token.secret.key=Base64-encoded-secret-key认证方式
| 方式 | 说明 |
|---|---|
| 控制台登录 | 用户名/密码(默认 nacos/nacos,生产必须改) |
| OpenAPI Token | 请求头 accessToken |
| 客户端认证 | 客户端配置 username/password(2.2+ 支持) |
客户端接入认证
yaml
spring:
cloud:
nacos:
discovery:
username: nacos
password: your-password
config:
username: nacos
password: your-password安全基线
- 修改默认账号密码,或对接统一认证(LDAP/SSO)
- 开启认证后所有 OpenAPI 需 Token
- 网络隔离:Nacos 只对内网暴露,控制台加白名单
- 敏感配置加密存储(对接外部加密插件)
监控告警
指标采集
Nacos 暴露 Prometheus 指标:
/nacos/actuator/prometheus关键指标:
| 指标 | 含义 | 告警建议 |
|---|---|---|
| nacos_monitor_service_count | 服务数量 | 突增告警 |
| nacos_monitor_raft_leader_count | Raft Leader 数量 | 不为 1 时告警 |
| nacos_monitor_distro_task_queue_size | Distro 任务队列 | 持续增长告警 |
| nacos_monitor_connection_count | gRPC 连接数 | 突降(客户端失联)告警 |
| JVM 指标(heap/gc) | 节点健康 | GC 异常告警 |
告警规则示例
# Prometheus 告警
- alert: NacosRaftLeaderDown
expr: nacos_monitor_raft_leader_count != 1
for: 1m
labels: { severity: critical }
- alert: NacosConnectionDrop
expr: nacos_monitor_connection_count < 100
for: 5m
labels: { severity: warning }日志
日志目录:logs/
├─ nacos.log 主日志
├─ naming-server.log 注册中心
├─ config-server.log 配置中心
└─ jraft.log 一致性协议日常巡检关注:异常心跳、同步失败、选举抖动、OOM。
常见问题
- 集群部署后数据不一致? 检查是否所有节点共用同一 MySQL、Distro/JRaft 是否正常、时钟是否同步。
- gRPC 端口不通? 9848/9849 未放通,客户端连不上服务端(注册/发现失败)。
- 认证开启后客户端报 403? 客户端需配置 username/password,Token 过期需刷新。
- 节点重启后注册数据丢失? 临时实例本来就存内存,重启后客户端会自动重注册;持久实例/配置在 MySQL 不丢。