NACOS 2.4.1 數據庫表詳解
-----------------------------------------------------------------------------------------
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: prod
service: 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 {
// 初始化 NamingService
NamingService namingService = NamingFactory.createNamingService("127.0.0.1:8848");
// 創建實例對象
Instance instance = new Instance();
instance.setIp("192.168.1.100"); // 實例 IP
instance.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 適合程序自動化查詢。
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------

浙公網安備 33010602011771號