Nacos 接入示例
本示例演示如何在 VextJS 中集成 Nacos,实现服务注册与发现、运行期动态配置,以及启动期远程配置补丁。
VextJS 提供官方 Nacos 插件 @devcodex/nacos,封装了注册/发现与运行期配置订阅流程。对于必须在框架配置冻结前生效的内容(如数据库配置),应使用 src/config/bootstrap.ts 的 bootstrap config provider。
推荐分层使用:
- 服务注册/发现、运行期动态开关:直接使用官方插件
@devcodex/nacos - 启动期数据库/密钥/基础设施配置:使用
src/config/bootstrap.ts拉取 Nacos 配置并返回 patch :::
前置条件
- 先按快速开始准备 Vext TypeScript API 项目及 dev/build/start 命令。
- 当前框架要求 Node.js
^20.19.0 || >=22.12.0。 - 准备可访问的 Nacos 服务端,确认 namespace 的实际 ID、分组、鉴权与客户端网络。插件默认 namespace 为 public;若部署使用其他 ID,应显式配置。
- 2026-09-25 核对的插件为
@devcodex/nacos@0.2.10,其 Vext peer 范围为>=0.3.4,内部 JavaScript SDK 为nacos@2.6.3;SDK 版本不是 Nacos Server 版本。此处不宣称所有服务端版本均经过验证,兼容性以插件发布说明与实际环境验证为准。
一、推荐:使用 @devcodex/nacos 官方插件
1. 安装
2. 配置(src/config/default.ts)
说明:
config适合单配置场景configs适合基础配置 + 环境覆盖配置拆分- 两者同时存在时按
config -> configs[0] -> configs[1] ...深合并,后者优先,数组整体替换;初次演示只使用 config。 - 显式插件参数与 app.config.nacos 是浅合并,传入 service 会替换整个 service 对象。
- 鉴权开关由服务端决定,不能由“2.x”推断默认开启,见Nacos 鉴权文档。
3. 注册插件(src/plugins/nacos.ts)
4. 读取功能开关
Nacos 配置必须是 JSON 对象。此处只接受字段值严格等于 true 的开关,错误类型不会被当作开启。当前插件保持 remoteConfig 顶层对象引用并原地更新字段;初次拉取失败时该属性可能尚不存在,因此请求时通过 req.app 读取并提供默认值。已缓存的嵌套对象引用不保证随更新刷新。
5. 启动并验证
先在 Nacos 控制台的对应 namespace / DEFAULT_GROUP 创建 dataId 为 order-service 的 JSON:
在应用目录运行:
响应应为200,默认包装的 data.enabled 为 true。将远程字段改为 false,等待订阅更新日志后再次请求,应变为 false;未知 key 默认为 false。控制台应显示 order-service 的3000端口实例。停止开发服务后,再用生产路径复验:
停止应用后确认实例已注销。服务注册地址必须能被其他消费者访问;127.0.0.1 仅适合本机演示。启动前注册成功不代表 HTTP 已开始监听,readiness 和负载均衡摘流仍需部署层安排。生产配置、鉴权与网络连通性应在实际 Nacos 环境验证。
二、扩展配置与服务发现
显式插件参数
也支持显式传参(覆盖 app.config.nacos):
动态端口(与 app.config.port 保持一致)
config/default.ts 中的 service.port 是静态值,无法读取最终合并后的端口号。
若各环境端口不同(如 sit: 10019 / prod: 20019),推荐在插件中动态注入:
这样 config/default.ts 里 service.port 仅作类型占位,实际注册端口由 app.config.port 决定,
各环境只需在对应 config 文件设置 port: 10019,nacos 自动跟随。
启动期远程配置推荐走 src/config/bootstrap.ts
如果你希望在 MonSQLize 初始化之前 就从 Nacos 拉取数据库配置,不要把这一步放在普通插件里;推荐直接使用 @devcodex/nacos 提供的 createNacosBootstrapProvider():
在所列 db-config 分组准备 config.json,根对象应直接使用 Vext 配置结构,例如 database;不要再包一层 remoteConfig。provider 拉取后客户端会关闭,不会继续订阅。required:true 时拉取/解析失败或超时会阻止启动;普通运行插件的初次配置拉取失败则只记录警告。配置优先级是 default < config profile < local < provider < CLI,其中 local 仅 development/test 加载,详见配置指南。
:::info 当前边界
createNacosBootstrapProvider() 只负责启动期批量拉取并深合并 JSON 对象 patch,适合数据库、密钥、基础设施配置这类“必须在配置冻结前生效”的内容。
这份返回值会进入 app.config 的 provider patch 合并链路,不会自动变成 app.remoteConfig。
它不负责:
- 服务注册
- 服务发现
app.nacos挂载app.remoteConfig注入与运行期订阅更新
这些运行期能力仍然由 nacosPlugin() 负责。
如果你需要:
- 服务注册 / 服务发现
- 与插件一致的
app.remoteConfig行为 - 配置变更后的持续订阅更新
都应该继续在 src/plugins/nacos.ts 中使用 nacosPlugin() 处理,而不是在 bootstrap 阶段完成。
bootstrap 阶段的服务发现边界
默认不能直接使用 app.nacos!.discover()。
原因是 src/config/bootstrap.ts 运行在 Vext App 创建之前:
- 此时还没有
app nacosPlugin()也还没有执行- 因而不存在
app.nacos/app.remoteConfig
所以推荐边界是:
- 启动期只做配置 patch 拉取 →
createNacosBootstrapProvider() - 运行期服务注册 / 服务发现 / 配置订阅 →
nacosPlugin()
运行期动态配置继续使用 app.remoteConfig
如果配置只影响运行期功能开关、灰度策略、外部 API 地址等,不需要参与 database / plugins / middlewares 初始化,则直接使用 @devcodex/nacos 的配置订阅能力即可:
- 初次启动后插件会拉取 Nacos 配置并挂载到
app.remoteConfig - 后续配置变更会自动更新
app.remoteConfig - 无需重启服务
实际行为取决于启用项:
- enabled:false、无 serverAddr 或既无配置源也无 service 时跳过初始化,不挂载相关扩展。
- 配置 service 才创建 Naming Client、注册实例并挂载 app.nacos;只有配置订阅时不能使用 discover。
- 配置 config/configs 才拉取并订阅 app.remoteConfig;非法 JSON/非对象变更警告并保留该来源上一版,空内容移除该来源。
- 同时启用时,关闭按 LIFO 注销实例并关闭 Naming Client,再关闭 Config Client。注销失败会记录警告,不能把调用结束视为服务端已确认摘除。
- 包导入提供 VextApp/VextConfig 类型增强,不代表运行期已初始化。app.config 保持冻结,动态配置不会自动重建数据库或限流中间件。
使用服务发现
该进阶 Service 假定另一个 user-service 已注册且提供 /api/users/:id;可由本应用路由调用 app.services.user.getUser(id)。discover 无健康实例时抛错,返回的 URL 使用 http。selectInstances 可以取得实例列表,但权重/一致性哈希选择仍需调用方实现。
多配置运行期示例
这种方式适合:
- 基础开关 + 环境覆盖
- 通用服务配置 + 租户/区域增量配置
- 运行期灰度参数分层维护
三、运行边界与排查
服务发现缓存(高频调用场景)
discover 每次调用 Naming Client 的 selectInstances;是否访问网络取决于 SDK 的实例缓存/订阅状态。只有测量出需要时才增加上层缓存。下面片段限定单应用、默认分组,用于演示 TTL:
缓存单个 URL 会暂时固定流量到同一实例,并可能继续访问已下线节点;失败时需要清除并重新发现。多应用、namespace 或 group 共存时,应隔离缓存并将这些维度纳入键,不能共享这里的 name-only Map。
依赖诊断端点
这个独立路径检查 Nacos 依赖,不覆盖框架自带 /health:
访问 /nacos-status;503 表示本例依赖检查未通过。实例查询可能使用 SDK 缓存,因此200不等于对 Nacos 服务端做了实时连通探测。
Nacos 配置数据格式
控制台中创建配置时使用 JSON:
订阅更新只改变 app.remoteConfig。业务代码需在使用时读取这些字段;它们不会自动改变 app.config.rateLimit 等已初始化框架设置。
四、下一步
- 📦
@devcodex/nacosnpm 包 — 完整 API 文档与变更日志 - 🔭 OpenTelemetry 接入示例 — 完整可观测性
- 🔌 插件系统 —
definePlugin()自定义插件 - 🌐 app.fetch — 内置 HTTP 客户端(超时/重试/requestId 传播)