
控制台点一次服务列表后端拦截器链和查询走了这条路控制台模块源码解析文章目录控制台点一次服务列表后端拦截器链和查询走了这条路控制台模块源码解析你在控制台点开服务列表的那一下控制台的 API 设计三类接口服务列表查询数据从哪来关键点分页在内存里做服务详情多一步拿元数据配置管理控制台的读写复用核心 API历史查询一键回滚权限校验拦截器链在哪一层拦人Secured 注解 AuthFilter鉴权的三个环节一张图带走控制台模块全景你在控制台点开服务列表的那一下打开 Nacos 控制台点服务管理 → 服务列表页面刷出一堆服务名、实例数、健康状态。这个动作背后请求先过了什么校验服务列表数据是从 MySQL 查的还是内存拿的你点编辑配置再点发布权限是在哪一层拦下没权限的用户的这篇文章拆开 console 模块看清楚控制台的三件事API 怎么设计、服务/配置数据怎么查、权限校验的拦截器链怎么工作。这是第十篇服务端源码的收尾——前三篇讲了启动、注册、配置这篇把人怎么操作它讲清楚。⚠️ 本文基于 Nacos 2.3.0 源码。2.3 版本开始控制台模块nacos-console逐步与核心 API 解耦独立成nacos-console与nacos-console-ui。若你用的是更早版本控制台 API 与 naming/config 的 Controller 是耦合在一起的包路径会有差异。控制台的 API 设计三类接口控制台的后端 API 主要分三类都在com.alibaba.nacos.console包下以及复用的 naming/config Controller接口类型典型入口类路径前缀作用服务管理CatalogController/v1/ns/catalog服务列表、详情、实例查询配置管理ConfigController/v1/cs/configs配置增删改查、历史、回滚系统管理HealthController/NamespaceController/v1/console命名空间、集群状态、健康检查控制台前端React 写的 SPA通过这些 REST API 拿数据后端不做页面渲染纯粹是 JSON 接口。服务列表查询数据从哪来点服务列表走的是CatalogController。核心问题数据是查 MySQL 还是读内存答案读内存。临时实例根本不在 MySQL服务列表主要来自服务端的内存注册表。控制台前端GET /v1/ns/catalog/servicesCatalogControllerCatalogServiceV2ImplServiceManager / ServiceStorage内存注册表ClientServiceIndexesManager反向索引聚合实例分页 过滤(健康状态/关键字)返回 JSON: 服务名/实例数/健康数关键点分页在内存里做服务列表支持按服务名搜索、按健康状态过滤、分页。这些操作都在内存中完成// CatalogServiceV2Impl 中的分页查询publicObjectpageListService(StringnamespaceId,StringgroupName,StringserviceName,intpageNo,intpageSize,...){// 1. 从内存拿到所有服务名// 2. 按关键字过滤// 3. 内存分页// 4. 对每个服务聚合实例数、健康实例数}为什么不查库因为临时实例生产中占绝大多数只存内存。如果去查库只能查到持久化实例服务列表会缺一大半。这也是新手容易困惑的点——“我明明注册了服务数据库config_info里怎么没有”因为注册信息压根不进那张表。服务详情多一步拿元数据点进某个服务的详情除了实例列表还要展示服务级元数据保护阈值、选择器等。这部分数据存在NamingMetadataManager里是独立于实例数据的一份元信息。配置管理控制台的读写复用核心 API控制台的配置增删改查直接复用了第 10.3 篇讲的ConfigController。这里只讲控制台特有的两个功能历史版本和回滚。历史查询// HistoryController查询配置历史GetMappingpublicPageConfigHistoryInfolistConfigHistory(RequestParam(dataId)StringdataId,RequestParam(group)Stringgroup,...){// 从 his_config_info 表分页查询returnhistoryService.listConfigHistory(dataId,group,...);}还记得 10.3 篇提到的——每次发布都往his_config_info历史表写一条控制台的历史版本列表就是查这张表。一键回滚回滚的本质把历史表里某个版本的内容重新发布一次。选中历史版本 id从 his_config_info 取出旧内容调用 publishConfig 重新发布生成新的当前版本 新历史记录触发 ConfigDataChangeEvent 通知客户端回滚不是删除当前版本恢复旧版本而是用旧内容做一次新发布。所以回滚后历史记录里会多一条当前版本号继续递增可追溯性完整。权限校验拦截器链在哪一层拦人控制台每个操作都要过权限校验。这套机制是通过拦截器 注解实现的。Secured 注解 AuthFilterNacos 用一个AuthFilterServlet Filter拦截所有请求配合方法上的Secured注解判断权限// Controller 方法上标注需要的权限Secured(actionActionTypes.WRITE,resourceconfig)PostMappingpublicBooleanpublishConfig(...){...}关闭开启有没有请求进入AuthFilter鉴权开关开启?直接放行 ⚠️危险校验 accessToken (JWT)解析出用户身份Secured 要求的权限用户是否拥有?放行, 执行业务403 无权限鉴权的三个环节环节类做什么身份认证AuthFilterJwtTokenManager校验 token 有效性解析用户权限解析Secured注解声明这个接口需要什么资源的什么权限权限判定AuthConfigsNacosRoleService查 RBAC 表判断用户角色是否匹配⚠️ 高危提醒nacos.core.auth.enabledfalse时AuthFilter直接放行所有请求。这意味着任何人访问到 8848 端口就能改配置、删服务。生产环境必须开启鉴权且不要把 8848/9848 直接暴露公网。这是 Nacos 历史上多个 CVE 的根源。一张图带走控制台模块全景数据源API层权限层前端nacos-console-uiReact SPAAuthFilterJWT 校验 Secured 判权CatalogController服务列表/详情ConfigController配置增删改查HistoryController历史/回滚NamespaceController命名空间内存注册表服务/实例数据MySQL配置 历史 RBAC 权限前端 SPA → AuthFilter 统一鉴权 → 各 Controller → 服务数据读内存、配置/权限数据读 MySQL。记住这条分界线服务实例在内存配置和权限在库。