Nacos 3.x 兼容与废弃治理机制:六态兼容模型、410 Gone 废弃 API 门控与 Legacy 迁移路径
2026/9/10 0:50:11 网站建设 项目流程

Nacos 3.x 兼容与废弃治理机制:六态兼容模型、410 Gone 废弃 API 门控与 Legacy 迁移路径

【免费下载链接】nacosan easy-to-use dynamic service discovery, configuration and service management platform for building AI cloud native applications.项目地址: https://gitcode.com/GitHub_Trending/na/nacos

本文围绕 Nacos 仓库中的设计规格specs/en/design/compatibility-deprecation-spec.md展开,系统讲解 Nacos 对 API、SDK、存储字段、插件与实验性能力所采用的统一兼容与废弃治理规则。读完后你将能够:准确判断任意 Nacos 历史行为属于哪种兼容状态、知道被废弃端点返回 HTTP410 Gone的底层实现与重开开关nacos.core.api.compatibility.enabled的适用边界,并掌握 v1/v2 Legacy HTTP API 适配器、Legacy MCPmcpId与 A2A AgentCard 门面等当前已知兼容项的迁移路径与移除条件。

1. 规格定位与治理边界

Nacos 的 兼容与废弃规格 定义了跨模块共享的治理规则,覆盖 API、SDK、存储字段、插件扩展点与实验性能力。它与 Nacos 设计规格、资源模型规格 以及各公开接口规格互为补充,是整个specs/体系中的“规则层”文档。

该规格明确拥有以下四类决策权:

  • 历史行为如何被分类为canonical(规范行为)compatibility-only(仅兼容)deprecated(已废弃)pending removal(待移除)experimental(实验性)removed(已移除)
  • 废弃或仅兼容行为的文档要求
  • API、SDK 接口、存储字段、插件扩展点的迁移预期
  • 能力门控(ability-gated)回退的移除规则

值得强调的是,该规格不设定固定的发布日历:每一次具体的废弃行为仍需对应领域的维护者评审,并通过 Release Note 向用户传达。这避免了“按版本号一刀切”的治理僵化,把节奏判断留给各领域维护者。

2. 六态兼容模型:判断历史行为“该不该用”的标尺

规格第 2 节给出了 Nacos 兼容治理的核心状态机。任何历史行为(一个端点、一个 SDK 方法、一个数据库字段、一个插件配置键)都必须落入以下六种状态之一:

状态含义新开发规则
Canonical(规范)由规格定义、面向新使用场景的当前行为新代码与文档都应使用它
Compatibility-only(仅兼容)为避免破坏现有用户而保留,但不是目标模型除缺陷修复与迁移支持外不得扩展
Deprecated(已废弃)仍可用,但用户应迁移到替代方案必须记录替代方案与迁移指引
Pending removal(待移除)移除条件已明确的废弃行为只保留必要的兼容性测试与迁移指引
Experimental(实验性)尚未承诺为稳定行为允许在不兼容变更或删除时给出明确说明
Removed(已移除)当前版本不再支持规格仅在必要时描述迁移历史

两条附加规则容易被忽视但很关键:

  1. 新规格必须显式标注“非规范”行为——某个行为即使存在于代码、数据库结构、配置或历史文档中,也不足以让它获得 canonical 地位。换句话说,“代码里存在”不等于“应该继续使用”,规格才是唯一授权来源。
  2. 这条原则正是第 9 节废弃 V3 API 门控的哲学基础:与其让废弃端点无限期存活,不如用明确的门禁让它“可见地失效”。

3. 文档规则:废弃行为不得“静默消失”

规格第 3 节规定了文档层面的硬性要求:只要实现仍在支持,废弃或仅兼容的行为就不允许从文档中静默删除。它必须出现在专门的兼容性或废弃章节中,且该章节必须包含五个要素:

  • 当前状态(Deprecated / Compatibility-only / Pending removal 等);
  • 替代物:替代 API、字段、SDK 方法或插件模型;
  • 迁移指引
  • 兼容性风险:包括认证(auth)、可见性(visibility)或响应结构(response-shape)上的差异;
  • 移除条件(若已知)。

同时要求面向用户的主流程文档优先描述 canonical 行为,兼容章节必须处于明显的次要位置。这一条直接约束了 Nacos 各 HTTP API 文档的写法:例如在 V3 API Surface 规格 中,废弃端点被统一收纳在兼容小节而非与规范端点并列。

4. API 与 SDK 规则:兼容强度分层

规格第 4 节对不同接口的“长期兼容预期”做了分层:

  • Open API(开放 API)承担最强的长期兼容预期
  • Admin、Console、Maintainer SDK 以及插件提供的 API 演进可以更快,但一旦发生不兼容变更且用户可能依赖了已文档化的行为,仍必须提供迁移指引;
  • 废弃端点应收留在兼容章节,而不是继续当作主 API 呈现;新的 API 定义不允许“因为旧形状已经存在”就照抄 legacy 结构;
  • SDK 在合理范围内应对废弃的公开方法保持二进制兼容,尤其是 Java 的 client、api、plugin 模块;新 SDK 特性应把用户引向 canonical 接口,不应扩展已废弃的写接口或宽泛查询面

这一分层解释了仓库中不同模块的差异:client/maintainer-client/等 Java 模块对公共方法签名变化保持克制,而console/内部的 Console API 可以在版本间快速迭代(如第 9 节中 3.2.1 即废弃一批 Pipeline 路径参数式端点)。

5. Ability-Gated Fallback:混版本集群中的回退纪律

Nacos 集群滚动升级时常出现新旧版本节点共存。规格第 5 节确立了原则:能力协商(ability negotiation)是首选的混版本机制,客户端/服务端通过能力位声明自身支持范围,而不是靠服务端猜测。回退(fallback)只有在所属领域规格明确记录以下四项信息后才被允许:

  • 门控 canonical 行为的能力键(ability key)或条件
  • 精确的 fallback 行为
  • fallback 是否改变响应结构、一致性、安全性或性能
  • fallback何时可以移除

移除时机同样被约束:必须等到最小受支持的 server/client 版本矩阵不再需要该回退,或者社区明确接受该不兼容变更,才允许移除。这套规则与 客户端能力协商规格 配套,是 Nacos 滚动升级平滑性的制度保障。

6. 存储与 Schema 规则:兼容字段不得“借尸还魂”

规格第 6 节针对数据库与持久层:

  • 仅为兼容而保留的存储字段必须被文档标注为 compatibility field 或 pending-removal field;除非后续领域规格显式提升它,否则它不得获得新的领域语义
  • Schema 清理需要在正确性运维成本之间平衡:一个冗余字段可以暂时保留以避免用户频繁做 schema 变更,但新的规格、API、SDK 与文档不得在这个字段之上构建新行为

第 8 节给出了这条规则的真实案例:在 Nacos 3.3 线中,Config 默认命名空间的存储迁移(从 legacy 空 tenant 值到public),以及 Config beta/tag 旧表迁移到config_info_gray表,都被视为已移除(removed)的兼容行为。这意味着:从 3.0 之前版本升级的操作者,若曾使用默认命名空间或 beta 灰度发布,必须在升级前完成受影响的数据迁移。这是一条有实际运维后果的规则,而非纸面约定。

7. 插件与适配器:兼容别名的边界

规格第 7 节对两类“外围兼容面”分别立规:

插件 SPI:SPI 的兼容性归属其所属插件规格(见 插件规格总览)。插件可以保留历史配置键或扩展名作为兼容别名(compatibility aliases),但规范的插件查找与启用方式必须单独文档化——别名不能替代规范路径成为文档主角。

适配器(Adapter):对外暴露社区协议的适配器属于兼容面,而非 canonical 的 Nacos API 模型。它们可以有意跟随外部协议的结构或路由约定,但必须被文档标注为 adapter 行为;如果引入了未认证端点或额外端口,应当是 opt-in 的。第 10 节的 v1/v2 Legacy HTTP API 适配器正是按这条规则运作的典型代表。

8. 当前已知兼容项清单

规格第 8 节列出了当前仓库中的兼容/废弃示例(非穷尽清单,各领域的精确行为与迁移细节仍由对应领域规格负责):

  • v1/v2 HTTP API:已移出主 server 发行版,迁移至独立的nacos-api-legacy-adapter项目(见第 10 节);
  • pre-spec v3 兼容端点
  • AI Prompt legacy 端点legacy Pipeline REST 风格端点
  • legacy MCP Console 导入端点:默认禁用,在迁移到统一 AI 资源导入端点后,计划在Nacos 3.4.0移除;
  • legacy MCPmcpId输入/输出:作为兼容别名保留,规范管理已转为 Namespace 作用域的mcpName
  • legacy A2A AgentCard 门面:覆盖 Java、gRPC、Admin、Maintainer 与 Console 各层;
  • Naming API 定义的 service selector 字段与请求参数
  • Config 聚合字段及相关数据库列;
  • 历史插件配置键
  • 仍位于历史路径下的 OIDC 浏览器端点
  • Distributed Lock(分布式锁):在提升为 stable 之前属于实验性能力(对应 lock 规格)。

这份清单的价值在于:它为“某段旧代码/旧接口还能活多久”提供了唯一权威的索引。结合第 6 节所述的 3.3 线 Config 迁移案例,运维者在制定升级计划时应以该清单逐项核对自身使用面。

9. Deprecated V3 API 门控:默认关闭的废弃端点与 410 Gone

这是本规格中最具工程落地感的一节。仓库中存在一小批“待移除的废弃 v3 API”,它们默认被禁用,并接入统一的兼容门控:

废弃 API规范替代
GET /v3/admin/ai/pipelinesGET /v3/admin/ai/pipelines/list
GET /v3/admin/ai/pipelines/{pipelineId}GET /v3/admin/ai/pipelines/detail?pipelineId={pipelineId}
GET /v3/console/ai/pipelinesGET /v3/console/ai/pipelines/list
GET /v3/console/ai/pipelines/{pipelineId}GET /v3/console/ai/pipelines/detail?pipelineId={pipelineId}
POST /v3/console/ai/mcp/import/validatePOST /v3/console/ai/import/validate
POST /v3/console/ai/mcp/import/executePOST /v3/console/ai/import/execute

9.1 门控实现:从CompatibilityHelper到 410 Gone

被禁用的端点返回HTTP410 Gone,结果码为API_DEPRECATED,并在响应体中指明其规范替代端点。其核心实现只有 55 行,位于 CompatibilityHelper.java:

public final class CompatibilityHelper { public static final String API_COMPATIBILITY_ENABLED_KEY = "nacos.core.api.compatibility.enabled"; private static final String DEPRECATED_API_MESSAGE = "Current API is deprecated. Please use API(s) `%s` instead, or set `%s=true` " + "in application.properties during migration."; /** * Check whether deprecated API compatibility is enabled. */ public static void check(String alternatives) throws NacosApiException { if (EnvUtil.getProperty(API_COMPATIBILITY_ENABLED_KEY, Boolean.class, false)) { return; } throw new NacosApiException(HttpStatus.GONE.value(), ErrorCode.API_DEPRECATED, String.format(DEPRECATED_API_MESSAGE, alternatives, API_COMPATIBILITY_ENABLED_KEY)); } }

三个实现要点与规格逐条对应:

  1. 默认关闭EnvUtil.getProperty(..., Boolean.class, false)的默认值为false,即开关缺省状态下废弃端点直接抛异常——与“默认禁用”的规格要求一致;
  2. 410 Gone+API_DEPRECATEDHttpStatus.GONE.value()即 410;ErrorCode.API_DEPRECATED定义于 ErrorCode.java(错误码40000, "API deprecated.",位于api模块的 v2 模型包中,可被所有 HTTP 响应层复用);
  3. 响应体自带迁移指引DEPRECATED_API_MESSAGE会填入调用方传入的alternatives(替代端点)与开关名,让调用方(包括 Agent 与脚本)无需查文档即可自助迁移。

配套的单测 CompatibilityHelperTest.java 验证了两个分支:开关关闭时抛出带替代信息的异常、开关打开后check(...)放行。

9.2 端点如何接入门控

以 Admin 侧 Pipeline 控制器 PipelineAdminController.java 为例,两个废弃路径参数式端点标注了@Deprecated(since = "3.2.1", forRemoval = true),方法体第一行即调用门控:

/** * Get pipeline execution detail by ID in path. * * @deprecated since 3.2.1, for removal in a future release. Use {@code GET .../detail?pipelineId=}. */ @Since("3.2.0") @Deprecated(since = "3.2.1", forRemoval = true) @GetMapping("/{pipelineId}") @Secured(action = ActionTypes.READ, signType = SignType.AI, apiType = ApiType.ADMIN_API) public Result<PipelineExecution> getPipeline(@PathVariable String pipelineId) throws NacosException { CompatibilityHelper.check( "GET /v3/admin/ai/pipelines/detail?pipelineId={pipelineId}"); return Result.success(pipelineQueryService.getPipeline(pipelineId)); }

注意一个细节:门控检查发生在@Secured认证鉴权之后@Secured由框架切面先执行),因此即使端点被禁用,访问者仍会被正确认证并拿到“指向替代端点”的 410 响应,而不是笼统的 401/403——这保证了迁移期错误信息对认证用户是可消费的。

Console 侧的 ConsolePipelineController.java 做了对称的门控;legacy MCP 导入端点在 ConsoleMcpController.java 中,Javadoc 明确标注 “Planned for removal in Nacos 3.4.0”,与规格第 8 节的移除计划完全吻合。相应地,PipelineAdminControllerTestConsolePipelineControllerTestConsoleMcpControllerTest以及test/openapi-test下的PipelineAdminApiOpenApiITCaseMcpConsoleApiOpenApiITCase等集成测试覆盖了门控开/关两种状态下的响应契约。

9.3 运维开关:nacos.core.api.compatibility.enabled

运维人员可以在迁移期间临时重开全部已接入门控的端点,只需在application.properties中设置:

nacos.core.api.compatibility.enabled=true

发行版默认配置 application.properties 中以注释形式给出了该键(默认关闭):

# nacos.core.api.compatibility.enabled=false ### Enabled for legacy open API compatibility provided by nacos-api-legacy-adapter # nacos.core.api.compatibility.client.enabled=true

该开关的四条设计约束(规格第 9 节原文要点):

  • 有意的共享开关:它只作用于“显式使用了 v3 兼容门控”的 API,即上文表格中的 6 个端点,不是全局兼容总闸;
  • 不替代 audience-specific 开关nacos-api-legacy-adapter拥有的分受众开关(如配置注释中提到的nacos.core.api.compatibility.client.enabled)不受此影响,两套机制互不越权;
  • 不绕过安全:重开后认证与鉴权仍然生效(如上所述@Secured先于业务逻辑执行);
  • 临时性:定位为“迁移期间临时重开”,不是长期兼容契约。

另一个关键变更:旧的nacos.ai.resource.import.legacy-mcp-api-enabled属性已不再被识别(代码库中检索不到该键的读取逻辑,bootstrapdistributionapplication.properties中均已移除);在 插件规格 中,direct user URL 兼容与 legacy MCP 导入适配器本身也被计划于Nacos 3.4.0移除。Legacy MCP 直接 URL 导入现在额外要求nacos.ai.resource.import.allow-user-url=true(默认配置见 application.properties:#nacos.ai.resource.import.allow-user-url=false,即默认关闭),且运维侧应优先使用受管 source 配置——更完整的操作指引可参考 AI 资源导入运维指南。

10. Legacy HTTP API 适配器:v1/v2 出主发行版后的规则

Nacos 3.2.0 线起,legacy 的 v1 与 v2 HTTP API 不再属于默认 Nacos server 发行版,而是由独立项目nacos-api-legacy-adapter提供,作为一个独立的兼容面。规格为其设定了五条规则:

  1. v3 HTTP API 与当前 SDK 是规范迁移目标——适配器的存在不改变方向;
  2. 适配器是临时迁移辅助,不是续命的 API 契约(“not a renewed API contract”);
  3. 适配器必须显式安装:例如把其 jar 放入 Nacos 的plugins目录,或作为内嵌/自定义应用的依赖加入;
  4. 适配器版本必须与目标 Nacos server 版本匹配
  5. 适配器不保证被未来版本支持,也不是定义新 v1/v2 行为的地方。

对文档的连带要求是:领域规格提及 legacy v1/v2 行为,仅限两种场合——作为迁移上下文,或当前兼容路径确实依赖它。这与配置文件中### Enabled for legacy open API compatibility provided by nacos-api-legacy-adapter的注释相互印证:该注释明确把 adapter 兼容性开关归因于外部适配器,而非 server 自身能力。

11. Legacy A2A Agent 门面:按受众划分的兼容窗口

规范 Agent 模型使用type=agent、协议无关的 Version 与 RAD 发现(详见 A2A Agent 规格、RAD 协议规格 与 Agent 管理规格)。历史 A2A AgentCard 各层表面属于compatibility-only,在服务端边界做适配转换。规格刻意按受众设置了不同的兼容窗口

受众兼容窗口
JavaA2aService与 legacy A2A gRPC payload尚无移除版本
Admin/v3/admin/ai/a2aA2aMaintainerService支持到4.0.x兼容窗口
Console/v3/console/ai/a2a支持到3.4.x兼容窗口,捆绑 UI 完成迁移后可移除

两条边界规则同样重要:不得仅向这些门面添加新能力——新开发一律面向 Agent Management 与 RAD 契约;历史数据迁移与混 server 滚动升级属于独立的迁移计划,不会仅凭它们就延长 API 兼容窗口

12. Legacy MCP 标识符:mcpId的退役与mcpName的接管

规范 MCP 管理以namespaceId + type=mcp + mcpName三元组标识 Resource。UUID 形态的mcpId作为公开资源标识符已被废弃,但它仍保留两个角色:内部物理存储别名(internal physical-storage alias)与 legacy 线上字段(legacy wire field)。各表面的兼容状态被精确切分:

表面状态规则
新的 Admin/Console/Maintainer 生命周期 APICanonical接受mcpName与可选 Version;不再新增mcpId
既有 Admin/Console/Maintainer 的仅 ID 输入Deprecated compatibility在请求的 Namespace 内解析恰好一个AiResource.ext.mcpId,然后按规范名称鉴权并操作
既有 model、event、create/release 响应及嵌套McpServerBasicInfo.id字段Active compatibility在物理 Config 坐标与当前消费者仍需其存在期间,保持线上结构与取值不变
MCP gRPC 请求中顶层AbstractMcpRequest.mcpIdIgnored and deprecated保留其字段编号(field number),不实现 ID 查找,各 handler 维持当前的 name 要求

工程上最严格的一条是 legacy ID 查找的实现限制:不允许使用最终一致性的 Search、不允许使用历史 Manifest/Config 身份查找、不允许建立 MCP 专用的内存索引,也不为此废弃路径新增任何表或列。这从实现层面杜绝了“兼容路径悄悄长出第二套真相来源”的风险。移除mcpId需要一次独立的迁移(涵盖 Config 坐标、直连消费者、SDK 模型与线上响应),且首次承载生命周期的迁移不定义移除版本;精确行为归属 MCP Server 规格。

12.1 Legacy MCP Maintainer 方法的废弃与迁移对照

legacyMcpMaintainerService的 detail 与 direct-online 创建/更新方法自Nacos 3.3.0 起废弃,计划于 Nacos 4.0.0 移除,兼容窗口内运行时行为保持不变。调用方应按以下对照迁移:

废弃操作规范替代
Serving 投影 detaillistMcpServerVersions选定精确 Version,再用getMcpServerVersion获取
local/remote/泛化的 direct-online 创建createMcpServer(McpServerDraftRequest),再submitMcpServerVersion;若适用评审,批准后显式publishMcpServerVersion
Direct-online 更新新版本用createMcpServer(McpServerDraftRequest),已有草稿用updateMcpServer(McpServerDraftRequest),随后 submit,必要时 publish

同时规格划出了一条“暂不废弃”的边界:legacy 跨资源 list/search 与 published-Version 或 full-Resource 删除方法未被本次决策废弃——因为类型化生命周期表面尚未提供语义等价的替代,必须先经过独立的 API 设计与废弃评审才能设定移除版本。这体现了该规格的一贯立场:没有等价替代,就不宣布废弃

13. 总结与延伸阅读

这份兼容与废弃规格的本质,是把“哪些东西还活着、活到什么时候、往哪里迁移”从各模块的隐性约定,提升为一套可审计、可测试、可执行的治理制度:六态模型负责分类,文档规则防止静默删除,ability-gated fallback 约束混版本回退,存储与插件规则防止兼容字段语义漂移,而CompatibilityHelper门控与 legacy 适配器则把制度落实到 HTTP 410 响应与发行版边界上。

延伸阅读(均在仓库specs/en/下):

  • HTTP API 规格 与 V3 API Surface:废弃端点在兼容章节中的具体呈现;
  • SDK 规格:SDK 二进制兼容与规范接口引导;
  • 客户端能力协商规格:ability-gated fallback 的协商基础;
  • 资源模型规格 与 持久化与 Dump 规格:存储兼容字段规则的上位依据;
  • 集成与适配器规格:适配器兼容面的通用规则;
  • MCP Server 规格:mcpId兼容行为的精确领域定义;
  • AI 资源导入运维指南:导入端点迁移的操作侧文档。

【免费下载链接】nacosan easy-to-use dynamic service discovery, configuration and service management platform for building AI cloud native applications.项目地址: https://gitcode.com/GitHub_Trending/na/nacos

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询