-----------------------------------------------------------------------------------------
mysql-schema.sql 脚本):一、配置管理核心表
1. config_info
- 用途:存储配置中心的核心配置数据。
- 核心字段:
id:主键(自增)。data_id:配置 ID(唯一标识一个配置)。group_id:配置分组(默认DEFAULT_GROUP)。tenant_id:命名空间 ID(多租户隔离)。content:配置内容(文本类型)。md5:内容的 MD5 值(用于变更检测)。type:配置类型(如properties、yaml)。gmt_create/gmt_modified:创建 / 修改时间戳。
- 索引:
uk_configinfo_datagrouptenant:联合唯一索引(data_id,group_id,tenant_id)。idx_did:基于data_id的索引,加速查询。
2. his_config_info
- 用途:存储配置历史版本。
- 核心字段:
nid:历史记录 ID(自增)。data_id/group_id/tenant_id:关联config_info的配置信息。op_type:操作类型(I- 插入、U- 更新、D- 删除)。src_user:操作用户。
- 关联关系:通过
data_id/group_id/tenant_id与config_info关联。
3. config_info_aggr
- 用途:存储聚合配置(多个子配置合并为一个)。
- 核心字段:
datum_id:子配置 ID。data_id/group_id/tenant_id:父配置信息。content:子配置内容。
- 场景:用于微服务中合并多个配置文件。
4. config_info_beta
- 用途:存储灰度发布的配置(仅限特定 IP 可见)。
- 核心字段:
beta_ips:允许访问的 IP 列表(逗号分隔)。
- 关联关系:与
config_info结构相同,新增beta_ips字段。
二、服务注册与发现核心表
1. service_info
- 用途:存储服务的元数据(如服务名称、分组、命名空间等)。
- 核心字段:
id:服务 ID(自增)。service_name:服务名(格式为group@@serviceName)。namespace_id:所属命名空间 ID。group_name:服务分组。health_check_type:健康检查类型(如HTTP、TCP)。up:服务整体是否可用(布尔值)。
- 索引:
uk_service_name:联合唯一索引(service_name,namespace_id)。
2. instance_info
- 用途:存储服务的具体实例信息(如 IP、端口、权重等)。
- 核心字段:
id:实例 ID(自增)。service_name:关联的服务名(与service_info.service_name对应)。ip/port:实例地址和端口。healthy:实例是否健康(布尔值)。weight:负载均衡权重(默认1.0)。ephemeral:是否为临时实例(临时实例下线后自动删除)。
- 索引:
idx_service_name:基于service_name的索引,加速服务查询。
3. cluster_info
- 用途:存储服务集群信息(如集群名称、健康检查配置)。
- 核心字段:
id:集群 ID(自增)。service_name:关联的服务名。cluster_name:集群名称(默认DEFAULT)。health_check_port:健康检查端口。
- 关联关系:通过
service_name与service_info关联。
三、权限控制表
1. users
- 用途:存储系统用户信息(用于控制台登录)。
- 核心字段:
username:用户名(主键)。password:加密后的密码(默认nacos用户密码为$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu)。enabled:用户是否启用。
2. roles
- 用途:存储用户角色(如
ROLE_ADMIN)。 - 核心字段:
username:关联的用户名。role:角色名称。
- 索引:
idx_user_role:联合唯一索引(username,role)。
3. permissions
- 用途:存储角色权限(如某个角色对某个资源的操作权限)。
- 核心字段:
role:角色名称。resource:资源路径(如/nacos/v1/ns/instance)。action:操作类型(如read、write)。
- 索引:
uk_role_permission:联合唯一索引(role,resource,action)。
四、集群与元数据表
1. raft_config
- 用途:存储集群模式下的 Raft 配置(如节点状态、日志索引)。
- 核心字段:
id:主键。key:配置键(如raft_term、commit_index)。value:配置值。
2. distributed_lock
- 用途:存储分布式锁信息(用于协调集群节点操作)。
- 核心字段:
lock_key:锁键(唯一标识一个锁)。lock_value:锁持有者信息。expire_time:锁过期时间。
五、其他辅助表
1. tenant_info
- 用途:存储命名空间(租户)的基本信息。
- 核心字段:
tenant_id:命名空间 ID(主键)。tenant_name:命名空间名称。description:描述。
2. group_capacity
- 用途:存储分组的容量限制(如配置数量、单个配置大小上限)。
- 核心字段:
group_id:分组 ID。quota:配额(0 表示无限制)。usage:已使用量。
六、表结构关联关系
-
配置管理:
config_info与his_config_info通过data_id/group_id/tenant_id关联。config_info_beta是config_info的扩展表,新增beta_ips字段。
-
服务注册:
service_info与instance_info通过service_name关联。service_info与cluster_info通过service_name关联。
-
权限控制:
users→roles→permissions通过username/role关联。
七、数据库初始化
- 脚本来源:
- 从 Nacos 官方仓库下载对应版本的
mysql-schema.sql:bashwget https://raw.githubusercontent.com/alibaba/nacos/2.4.1/distribution/conf/mysql-schema.sql
- 从 Nacos 官方仓库下载对应版本的
- 执行步骤:
- 创建数据库(如
nacos_config)。 - 执行 SQL 脚本创建所有表。
- 创建数据库(如
- 配置连接:
- 修改
nacos/conf/application.properties,添加数据库连接信息:propertiesspring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://localhost:3306/nacos_config?characterEncoding=utf8 db.user=root db.password=your_password
- 修改
八、版本差异说明
- 2.4.1 vs 2.5.0:
- 2.5.0 新增
config_info_gray表(灰度发布),而 2.4.1 使用config_info_beta。 - 部分字段(如
namespace_id)的索引策略可能微调,但核心结构一致。
- 2.5.0 新增
-----------------------------------------------------------------------------------------
mysql-schema.sql 及 Release Notes):一、2.0.x 基础版本(2.0.0 ~ 2.0.4)
- 配置管理:
config_info、his_config_info、config_info_aggr、config_info_beta(灰度配置)。 - 服务发现:
service_info、instance_info、cluster_info。 - 权限控制:
users(用户)、roles(角色)、permissions(权限)。 - 集群管理:
raft_config(Raft 协议配置)、distributed_lock(分布式锁)。 - 命名空间:
tenant_info。
- 权限表(
users/roles/permissions)首次在 2.x 中稳定支持,实现基于角色的权限控制(RBAC)。 - 服务发现表中
ephemeral字段(临时实例标识)成为核心字段,区分持久化与临时实例。
二、2.1.x 版本(2.1.0 ~ 2.1.2)
-
config_info表新增字段:encrypted_data_key:用于存储配置内容的加密密钥(支持配置加密功能)。- 背景:2.1.x 引入配置内容加密特性,该字段用于解密
content字段的加密内容。
-
permissions表优化:- 新增
resource字段的长度调整(从varchar(255)扩展为varchar(1024)),支持更长的资源路径(如复杂的 API 路径)。
- 新增
-
索引优化:
- 为
config_info的encrypted_data_key新增索引,加速加密配置的查询。
- 为
三、2.2.x 版本(2.2.0 ~ 2.2.3)
-
instance_info表新增字段:metadata:存储实例的元数据(如环境标签、版本信息等),支持更丰富的实例属性扩展。instance_id:实例唯一标识(原依赖ip:port组合,新增独立字段便于唯一标识)。
-
cluster_info表优化:- 新增
health_check_timeout字段:健康检查超时时间(毫秒),细化健康检查配置。
- 新增
-
distributed_lock表调整:- 新增
lock_owner字段:记录锁持有者的节点 ID,便于集群锁冲突排查。
- 新增
四、2.3.x 版本(2.3.0 ~ 2.3.2)
-
his_config_info表新增字段:app_name:关联的应用名称,便于按应用筛选配置历史。tenant_id字段从varchar(128)扩展为varchar(256),支持更长的命名空间 ID。
-
service_info表新增字段:selector:服务选择器配置(JSON 格式),支持基于标签的服务路由。metadata:服务级别的元数据(如服务描述、版本等)。
-
新增
config_tags_relation表:- 用途:存储配置与标签的关联关系,支持通过标签快速筛选配置。
- 核心字段:
id、tag_name(标签名)、tag_type(标签类型)、data_id、group_id、tenant_id。
五、2.4.x 版本(2.4.0 ~ 2.4.1)
-
config_info_beta表增强:- 新增
beta_desc字段:灰度配置的描述信息,便于管理灰度规则。
- 新增
-
roles表新增字段:role_desc:角色描述,支持对角色的用途进行说明(如 “只读角色”“管理员角色”)。
-
索引优化:
- 为
service_info的selector字段新增索引,加速基于选择器的服务查询。 - 为
instance_info的metadata字段新增全文索引,支持元数据的模糊查询。
- 为
六、2.5.x 版本(2.5.0 ~ 2.5.3)
-
新增
config_info_gray表:- 替代
config_info_beta表,专门存储灰度配置(支持按 IP、标签等多维度灰度)。 - 核心字段:
gray_ips(灰度 IP 列表)、gray_tags(灰度标签)、gray_desc(灰度描述)。
- 替代
-
config_info表字段调整:- 移除
beta_ips字段(灰度逻辑迁移至config_info_gray)。 - 新增
schema_version字段:配置的 schema 版本,用于兼容不同格式的配置解析。
- 移除
-
instance_info表字段扩展:weight字段从double(10,2)调整为double(16,6),支持更精细的权重设置(如 0.000001 粒度)。
七、总结:核心变化趋势
- 配置管理:从基础配置存储 → 支持加密、灰度(
beta→gray)、标签关联,表结构更细分。 - 服务发现:实例 / 服务元数据(
metadata)字段逐步丰富,支持更灵活的路由和筛选。 - 权限控制:字段长度扩展、新增描述信息,权限粒度更细。
- 性能优化:针对高频查询字段(如
service_name、metadata)持续优化索引。
- 跨版本升级时,需执行官方提供的
schema-upgrade.sql脚本(位于nacos/conf目录),自动处理表结构变更。 - 若自定义扩展表字段,升级前需备份数据,避免冲突。
-----------------------------------------------------------------------------------------
service_info、instance_info、cluster_info 这三张服务发现相关的表,这三张表是服务注册与发现功能的核心存储载体,在 2.x 版本中依然存在。如果在实际使用中没有找到这些表,通常与存储模式选择或初始化配置有关,具体原因如下:一、Nacos 服务发现数据的存储模式
1. 嵌入式存储(默认单机模式)
service_info、instance_info、cluster_info 表会被创建,但数据存储在 Nacos 进程内部的内存或本地文件(nacos/data/derby-data)中,无法通过外部数据库客户端(如 MySQL 客户端)直接查看表结构。2. 外部数据库存储(推荐生产模式)
service_info、instance_info、cluster_info 表会被显式创建,可通过数据库客户端直接查看。- 初始化脚本未执行完整:Nacos 2.x 的数据库初始化脚本(
mysql-schema.sql)包含所有核心表(包括服务发现相关表),若只执行了部分脚本(如仅配置管理相关表),会导致服务发现表缺失。 - 数据库连接配置错误:Nacos 实际连接的数据库与用户查看的数据库不一致(如配置文件中
db.url指向的库未初始化脚本)。 - 版本不匹配:使用了低版本的初始化脚本(如 1.x 脚本),而 2.x 对表结构有扩展,低版本脚本可能缺少部分字段,但核心表(
service_info等)仍会存在。
二、临时实例与持久化实例的存储差异
ephemeral=true)和持久化实例(ephemeral=false):- 临时实例:依赖客户端心跳维持存活,数据默认不持久化到数据库(仅在内存中存储,集群模式下通过 Raft 协议同步),因此
instance_info表中可能看不到临时实例的数据,但表本身依然存在。 - 持久化实例:数据会持久化到
instance_info表,即使客户端下线,数据也不会删除(需手动注销)。
三、如何确认表是否存在?
-
切换到外部数据库存储:在
nacos/conf/application.properties中配置 MySQL 连接,执行官方 2.x 版本的mysql-schema.sql脚本(可从 Nacos 仓库 下载对应版本),初始化后即可在 MySQL 中看到service_info、instance_info、cluster_info表。 -
检查嵌入式数据库文件:单机模式下,Derby 数据库文件位于
nacos/data/derby-data,可通过 Derby 客户端工具(如ij)连接查看表结构(需了解 Derby 连接方式,操作较复杂,不推荐)。
总结
service_info、instance_info、cluster_info 表是存在的,未找到的原因通常是:- 使用默认嵌入式 Derby 数据库,表结构不对外暴露;
- 外部数据库初始化不完整或连接配置错误;
- 仅使用临时实例,表中无数据导致误判。
-----------------------------------------------------------------------------------------
一、接口作用
二、参数说明
| 参数名 | 含义 | 示例值 / 说明 |
|---|---|---|
hasIpCount |
是否返回每个服务的实例数量(健康 + 不健康的总实例数) | true(返回)/ false(不返回) |
withInstances |
是否返回每个服务的具体实例详情(如 IP、端口等) | false(不返回实例详情) |
pageNo |
分页页码(从 1 开始) | 1(查询第 1 页) |
pageSize |
每页条数 | 20(每页返回 20 个服务) |
serviceNameParam |
服务名模糊查询参数(为空时查询所有服务) | 如 order-service 可筛选包含该名称的服务 |
groupNameParam |
服务分组模糊查询参数(为空时查询所有分组) | 如 DEFAULT_GROUP 可筛选该分组的服务 |
namespaceId |
命名空间 ID(服务隔离的维度,通常对应环境如 prod/test/dev) | prod(查询生产环境的服务) |
三、返回结果格式
hasIpCount=true 为例):{"totalCount": 50, // 符合条件的服务总数量"pageNumber": 1, // 当前页码"pagesAvailable": 3, // 总页数(totalCount / pageSize 向上取整)"serviceList": [ // 服务列表数组{"name": "DEFAULT_GROUP@@order-service", // 服务名(格式:分组名@@服务名)"groupName": "DEFAULT_GROUP", // 服务分组"namespaceId": "prod", // 命名空间ID"ipCount": 3 // 该服务的实例总数(因 hasIpCount=true 才返回)},{"name": "DEFAULT_GROUP@@user-service","groupName": "DEFAULT_GROUP","namespaceId": "prod","ipCount": 2}// ... 更多服务]
}
- 若
withInstances=true,每个服务项会新增instanceList字段,包含该服务的所有实例详情(IP、端口、健康状态等)。 - 若查询无结果,
serviceList为空数组,totalCount=0。
四、调用注意事项
-
权限认证:若 Nacos 开启了认证(
nacos.core.auth.enabled=true),调用时需在 HTTP 头中携带认证信息:httpHeader: Authorization=Bearer {token}(token可通过登录接口/nacos/v1/auth/login获取)。 -
命名空间存在性:
namespaceId=prod需已在 Nacos 中创建(否则返回空列表)。 -
服务可见性:只有注册到该命名空间的服务才会被查询到(临时实例和持久化实例均会被统计,除非实例被手动删除)。
五、使用场景
- 后端服务需要动态获取某个环境(如 prod)的所有服务列表,用于服务治理、监控或网关路由配置。
- 前端控制台展示服务清单,配合分页功能减轻数据加载压力。
-----------------------------------------------------------------------------------------
ephemeral=true 用于指定服务实例为临时实例(依赖客户端心跳维持存活,客户端下线后实例会被自动删除)。该参数的配置位置取决于服务注册的客户端类型(如 Spring Cloud 应用、原生 SDK 等),核心是在服务实例注册时指定该属性。一、Spring Cloud Alibaba 应用(最常用场景)
spring-cloud-starter-alibaba-nacos-discovery 注册到 Nacos,可在配置文件(application.properties 或 application.yml)中直接配置:配置示例:
# application.yml
spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848 # Nacos 服务端地址ephemeral: true # 设置为临时实例(默认值就是 true,可省略)# 其他配置(如命名空间、服务名等)namespace: prodservice: order-service
- 默认值:
ephemeral默认值为true,即不配置时默认是临时实例。 - 若要改为持久化实例,需显式设置
ephemeral: false。
二、原生 SDK 注册(如 Java SDK)
Instance 对象时,通过 setEphemeral(true) 方法指定:代码示例:
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;public class NacosRegisterExample {public static void main(String[] args) throws NacosException {// 初始化 NamingServiceNamingService namingService = NamingFactory.createNamingService("127.0.0.1:8848");// 创建实例对象Instance instance = new Instance();instance.setIp("192.168.1.100"); // 实例 IPinstance.setPort(8080); // 实例端口instance.setEphemeral(true); // 设置为临时实例(默认 true)// 注册实例(服务名、实例对象)namingService.registerInstance("order-service", instance);}
}
三、其他客户端(如 Go、Python 等)
ephemeral 属性,逻辑与 Java SDK 类似:- Go SDK:在
Instance结构体中设置Ephemeral: true。 - Python SDK:在注册实例的参数中添加
ephemeral=True。
核心说明
ephemeral是实例级别的属性,即同一个服务可以同时存在临时实例和持久化实例(通过不同客户端配置区分)。- 临时实例(
ephemeral=true)依赖客户端心跳:若心跳超时(默认 30 秒),Nacos 会将实例标记为不健康;若超过 90 秒未收到心跳,会删除该实例。 - 持久化实例(
ephemeral=false)不依赖心跳,客户端下线后实例仍会保留在 Nacos 中,需手动调用注销接口删除。
-----------------------------------------------------------------------------------------
ephemeral=true 的临时实例默认不持久化到数据库(instance_info 表),而是存储在内存中(集群模式下通过 Raft 协议同步)。查看临时实例的服务信息,主要通过 Nacos 控制台 或 Open API,以下是具体方法:一、通过 Nacos 控制台查看(最直观)
-
登录控制台访问 Nacos 控制台地址(默认
http://<nacos-server-ip>:8848/nacos),输入用户名 / 密码(默认nacos/nacos,若开启认证则使用配置的账号)。 -
进入服务详情页
- 在左侧菜单选择 服务管理 > 服务列表。
- 选择目标命名空间(如
prod),找到需要查询的服务(如order-service),点击服务名进入详情页。
-
查看实例列表在服务详情页的 实例列表 中,会显示该服务的所有实例(包括临时实例和持久化实例)。
- 临时实例会在 元数据 或 实例属性 中标记
ephemeral: true(不同 Nacos 版本显示位置可能略有差异)。 - 也可通过 健康状态 辅助判断:临时实例依赖心跳,若心跳超时会显示 “不健康”;持久化实例不依赖心跳,默认 “健康”。
- 临时实例会在 元数据 或 实例属性 中标记
二、通过 Nacos Open API 查询(适合程序调用)
ephemeral 字段筛选临时实例,具体如下:1. 接口信息
- 请求地址:
/nacos/v1/ns/instance/list - 请求方式:GET
- 核心参数:
参数名 含义 示例值 serviceName服务名(必填) DEFAULT_GROUP@@order-service(格式:分组名 @@服务名)namespaceId命名空间 ID(可选) prodhealthyOnly是否只返回健康实例 false(返回所有实例)
2. 调用示例(curl 命令)
# 替换为实际的 Nacos 服务端地址、服务名和命名空间
curl "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=DEFAULT_GROUP@@order-service&namespaceId=prod&healthyOnly=false"
3. 响应结果解析
hosts 数组包含所有实例信息,每个实例的 ephemeral 字段明确标识是否为临时实例:{"name": "DEFAULT_GROUP@@order-service","groupName": "DEFAULT_GROUP","namespaceId": "prod","hosts": [{"ip": "192.168.1.100","port": 8080,"healthy": true,"ephemeral": true, // 临时实例(ephemeral=true)"weight": 1.0,"metadata": {},// ... 其他字段(如集群名、心跳时间等)},{"ip": "192.168.1.101","port": 8081,"healthy": true,"ephemeral": false, // 持久化实例(对比参考)// ... 其他字段}],// ... 其他全局信息(如服务总数、集群信息等)
}
- 筛选临时实例:遍历
hosts数组,过滤出ephemeral: true的实例即可。
三、通过 Nacos 原生 SDK 查询(开发场景)
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingFactory;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;import java.util.List;public class QueryEphemeralInstances {public static void main(String[] args) throws NacosException {// 初始化 NamingService(连接 Nacos 服务端)NamingService namingService = NamingFactory.createNamingService("127.0.0.1:8848");// 查询服务的所有实例(包括临时和持久化)List<Instance> instances = namingService.getAllInstances("order-service", // 服务名"DEFAULT_GROUP", // 分组名"prod" // 命名空间 ID);// 筛选出临时实例(ephemeral=true)for (Instance instance : instances) {if (instance.isEphemeral()) { // 判断是否为临时实例System.out.println("临时实例:" + instance.getIp() + ":" + instance.getPort());}}}
}
四、注意事项
-
临时实例的存储特性:临时实例(
ephemeral=true)不会写入数据库instance_info表,因此直接查询数据库无法获取其信息,必须通过控制台、API 或 SDK 从 Nacos 服务端内存中读取。 -
权限认证:若 Nacos 开启了认证(
nacos.core.auth.enabled=true),调用 API 或 SDK 时需先通过登录接口获取token并携带认证信息(具体参考 Nacos 认证文档)。 -
实例存活判断:临时实例依赖客户端心跳,若超过心跳超时时间(默认 30 秒),Nacos 会将其标记为
healthy: false;若超过 90 秒未收到心跳,实例会被从列表中删除。
ephemeral=true 的临时实例信息,其中控制台适合人工操作,API/SDK 适合程序自动化查询。
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------