若依微服务 Nacos 2.x 控制台配置列表为空?一个 tenant_id 字段引发的血案

若依微服务 Nacos 2.x 控制台配置列表为空?一个 tenant_id 字段引发的血案

作者:挽安 场景:基于若依微服务(RuoYi-Cloud)从 0-1 搭建个人项目基座时,遇到 Nacos 2.5.4 控制台配置列表始终为空的诡异问题。排查过程曲折,根因出乎意料------不是缓存、不是 Redis、不是网络,而是一个数据库字段的"版本兼容性"坑。

一、问题背景

我在用若依微服务版(SpringCloud Alibaba 2025.0.0.0 + SpringBoot 3.5.16 + JDK17)做新项目基座,技术栈很新。按照若依官方流程:

  1. 本地装好 MySQL 8.0、Redis、Nacos 2.5.4
  2. 导入 3 个 SQL:ry_config_20260818.sql(Nacos 配置表)、ry_20260417.sql(业务库)、quartz.sql(定时任务表)
  3. 改 Nacos 的 application.properties 连 MySQL
  4. startup.cmd -m standalone 启动 Nacos

启动日志一切正常,甚至打印了让人安心的成功标志:

kotlin 复制代码
2026-09-09 13:53:19,731 INFO Nacos started successfully in stand alone mode. use external storage

use external storage 说明 Nacos 确实用了 MySQL 外部存储,不是退化用 derby 内置库。

但是------打开浏览器访问 http://localhost:8848/nacos,配置管理 → 配置列表,是空的!0 条配置!

二、排查过程(重点)

这个问题我排查了将近两个小时,走了不少弯路。下面按我实际的排查顺序写,每一步的判断逻辑都讲清楚。

第一步:怀疑 MySQL 里根本没数据

第一反应是 SQL 没导入成功。

sql 复制代码
SELECT COUNT(*) FROM `ry-config`.config_info;
-- 结果: 9

MySQL 里 9 条配置全在。那问题不在数据源。

第二步:怀疑 Nacos 启动时连不上 MySQL

启动日志说 use external storage,但万一日志骗我呢?我查 MySQL 的连接进程:

sql 复制代码
SELECT host, user, db, command, time, state, info
FROM information_schema.processlist
WHERE info IS NOT NULL;

结果只有我自己的查询进程,没有 Nacos 的长连接

但这不能说明 Nacos 没连上------Nacos 用的是连接池(HikariCP),空闲时连接会归还池里不一定活跃。这条线索不能下定论,只能存疑。

第三步:看 Nacos 的 dump 日志(关键转折)

Nacos 的配置加载流程是:MySQL → 启动时 dump 到本地磁盘 + JVM 内存缓存 → API 查询时从缓存读

我看 logs/config-dump.log

ini 复制代码
2026-09-09 13:53:15,068 INFO [all-dump] submit all task for 9 / 9, dbTime=32,diskTime=3
2026-09-09 13:53:16,077 INFO success to dump all config-info。

dump 成功了,9/9! 而且看 logs/config-server.log 也确认了:

lua 复制代码
2026-09-09 13:53:15,033 INFO start dump all config-info...
2026-09-09 13:53:16,077 INFO success to dump all config-info。

这就诡异了------日志说 dump 成功,MySQL 有数据,但 API 返回 0 条。

第四步:直接打 API 验证(绕过控制台前端)

控制台可能是浏览器缓存问题。我用 API 直接测:

powershell 复制代码
Invoke-WebRequest -Uri "http://localhost:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=20&tenant="

返回:

json 复制代码
{"totalCount":0,"pageNumber":1,"pagesAvailable":0,"pageItems":[]}

API 也是 0 条! 排除了前端缓存问题,问题确实在 Nacos 后端。

第五步:查磁盘缓存文件

既然 dump 说写磁盘了,那磁盘上有没有文件?

powershell 复制代码
Get-ChildItem "d:\develop\nacos\nacos-server-2.5.4\nacos\data\tenant-config-data\public\DEFAULT_GROUP\"

结果:9 个 yml 文件全在! 而且读 zjb-system-dev.yml 的内容,密码字段都正确。

这就更矛盾了:

  • MySQL 有 9 条 ✅
  • dump 日志说成功 ✅
  • 磁盘缓存文件 9 个 ✅
  • 但 API 返回 0 条 ❌

第六步:怀疑磁盘缓存损坏,清空 data 目录重启

我怀疑是第一次启动时 DNS 解析 jmenv.tbsite.net 失败(Nacos 默认尝试连阿里内网地址服务器),导致 data 目录状态不一致,后续重启继承了损坏的缓存。

于是:

  1. 停掉 Nacos 进程
  2. data 目录重命名为 data_old(备份)
  3. 重新启动 Nacos

结果------还是 0 条! 这条线索断了。问题不在磁盘缓存。

第七步:查 MySQL 的 tenant_id 字段(真凶浮现)

到这里我已经走投无路了。MySQL 有数据、dump 成功、磁盘有文件,但 API 返回 0。唯一的解释是------Nacos 查询 MySQL 时的 WHERE 条件不匹配

我查了一下 config_info 表的完整字段:

sql 复制代码
SELECT id, data_id, tenant_id, gmt_modified FROM config_info;

结果让我愣住了:

arduino 复制代码
id  data_id                 tenant_id
1   application-dev.yml      public
2   zjb-gateway-dev.yml      public
3   zjb-auth-dev.yml         public
...
9   sentinel-zjb-gateway     public

tenant_id 字段的值是字符串 'public'

而 Nacos 2.x 中,默认命名空间(也就是页面上显示的 public)在数据库里的 tenant_id 应该是空字符串 '' ,不是字符串 'public'

Nacos 查询配置时执行的 SQL 大概是:

sql 复制代码
SELECT * FROM config_info WHERE tenant_id = '' AND ...

而数据库里存的是 tenant_id = 'public',自然查不到。

三、根因分析

这和 Redis 有关吗?和缓存有关吗?

无关。

  • 不是 Redis 的问题(Redis 在这个场景下还没参与,Nacos 配置中心不用 Redis)
  • 不是 Nacos 磁盘缓存损坏的问题(清空 data 目录重启也没用,因为问题在 MySQL 源头)
  • 不是网络问题、不是 DNS 问题(虽然第一次启动因 jmenv.tbsite.net DNS 解析失败崩溃过,但后续重启都成功了)
  • 不是 Nacos 版本 bug

根本原因是:若依官方提供的 ry_config_20260818.sql 文件,是按 Nacos 1.x 的规范写的。在 Nacos 1.x 里,默认命名空间的 tenant_id 存字符串 'public' 是可以的;但 Nacos 2.x 改了规范,默认命名空间的 tenant_id 必须是空字符串 ''

这是一个典型的框架版本兼容性坑------若依的 SQL 模板没跟上 Nacos 2.x 的规范变更。

为什么 dump 日志说成功?

因为 dump 操作是全量读 MySQL 然后写磁盘和内存缓存,它不校验 tenant_id 的值合不合法。dump 成功 ≠ 查询时能查到。查询时 Nacos 会按 tenant_id='' 去匹配,存的是 'public' 就匹配不上。

四、解决方案

一行 SQL 修复:

sql 复制代码
UPDATE config_info SET tenant_id = '' WHERE tenant_id = 'public';

执行后验证:

perl 复制代码
data_id             tenant_id   tenant_len
application-dev.yml             0
zjb-gateway-dev.yml             0
zjb-auth-dev.yml                0
zjb-monitor-dev.yml             0
zjb-system-dev.yml              0
zjb-gen-dev.yml                 0
zjb-job-dev.yml                 0
zjb-file-dev.yml                0
sentinel-zjb-gateway            0

Nacos 会自动检测到 tenant_id 变化并刷新缓存,不用重启。再调 API:

json 复制代码
{"totalCount":9,"pageNumber":1,"pagesAvailable":1,"pageItems":[...]}

9 条配置全部出现! 控制台刷新也能看到了。

五、经验总结

这次排查给我几个深刻教训:

1. "日志说成功" 不等于 "功能正常"

Nacos 的 dump 日志说 success to dump all config-info,但这只代表"从 MySQL 读出来写到了缓存",不代表查询时能匹配到。读成功 ≠ 查询匹配成功,这是两个独立环节。

2. 排查顺序很重要

我的排查顺序是:MySQL 数据 → 进程连接 → dump 日志 → API 验证 → 磁盘缓存 → 清空重启 → 字段值。

如果一开始就查完整字段值(而不是只查 data_id),可能5分钟就定位了。但实际排查时人容易先怀疑"大问题"(连接、缓存、网络),忽略"小细节"(字段值)。

3. 框架版本兼容性是隐形地雷

若依的 SQL 模板是为 Nacos 1.x 写的,Nacos 2.x 改了 tenant_id 的规范,但若依没更新 SQL。这类"官方资料滞后于中间件版本"的坑非常多,比如:

  • Nacos 1.x → 2.x 的 tenant_id 规范变更
  • SpringBoot 2.x → 3.x 的 javax.*jakarta.* 包名变更
  • MySQL 5.7 → 8.0 的认证插件变更

用新版本中间件时,一定要查官方的版本迁移文档,不能盲目信任第三方框架提供的 SQL/配置模板。

4. 遇到诡异问题,先查字段值

排查思路应该是:

  1. 先查完整字段值SELECT * 而不是只查 id)
  2. 再查索引、连接、缓存这些"大件"

这次我浪费的时间,大部分花在怀疑"缓存损坏""DNS 问题"上,而真凶就藏在 tenant_id 这个不起眼的字段里。

六、写在最后

这个坑浪费了我将近两小时,但收获很大------让我真正理解了 Nacos 配置中心的加载链路:

scss 复制代码
MySQL(config_info 表)
    ↓ 启动时全量 dump
磁盘缓存(data/tenant-config-data/{tenant}/{group}/)
    +
JVM 内存缓存
    ↓ API 查询时
返回给客户端

以及一个关键认知:dump 成功 ≠ 查询能查到 ,中间还隔着一个 tenant_id 字段值的匹配逻辑。

希望这篇文章能帮到同样踩坑的朋友。如果你也在用若依微服务 + Nacos 2.x,导入 SQL 后控制台是空的,直接执行:

sql 复制代码
UPDATE config_info SET tenant_id = '' WHERE tenant_id = 'public';

一键解决。


技术栈:若依微服务(RuoYi-Cloud)+ SpringBoot 3.5.16 + SpringCloud Alibaba 2025.0.0.0 + Nacos 2.5.4 + MySQL 8.0 + JDK17

标签Nacos 若依 微服务 SpringCloud 踩坑记录

相关推荐
周杰伦fans1 小时前
ASP.NET Core Identity 从入门到实战:常见问题与解决方案
后端·asp.net
n8n1 小时前
Spring AI 三层架构详解:ChatModel → ChatClient → Controller,同步调用 vs 流式调用(SSE)
后端
小傅哥1 小时前
Java + DDD,1:1 复刻 Deepseek Harness 项目
前端·后端·ai编程
Lambert2811 小时前
AgentScope Java 从零(03):Agent 的记性默认全开,我在第 50 轮翻了车
后端·aigc
积硅步致千里1 小时前
Word 里的 .wmf 其实是 EMF:一次 metafile 转 PNG 排障
前端·后端
爱读源码的大都督2 小时前
DeepSeek面试官问:生产RAG系统回答不准确,该如何定位和优化?这样回答,能让面试官当场给你Offer!
java·后端·python
杨运交2 小时前
[069][公共模块]Spring Boot 全局异常处理与参数校验实战(下):校验异常精细化处理与 WebFlux 适配
java·spring boot·后端
Andya_net3 小时前
Spring Boot | 条件注解完全指南:从 @Conditional 到 @ConditionalOnExpression 的原理、实践与避坑
spring boot·后端·python
ly76893 小时前
Spring 中的 @Configuration 与 @Component 差异:为何代理时机决定 Bean 生命周期行为
java·后端·spring·注解·代理·bean生命周期