MCP第 6 篇:Spring AI Alibaba 封装 MCP:注册中心、网关与企业治理

第 6 篇:Spring AI Alibaba 封装 MCP------注册中心、网关与企业治理

📍 系列导航 :1. 认识 MCP | 2. 本地实战 | 3. 多能力工程 | 4. HTTP URL | 5. Spring AI | 6. 企业治理

6.1 本篇定位

前五篇解决"能跑、能交付"。本篇解决"企业级多团队、多 Server、可治理"。

⚠️ 说明:Spring AI Alibaba 的 MCP 支持仍在演进,具体 artifact、注解、配置键以官方文档和版本为准。本篇重点是架构思路和落地骨架,不是逐行 API 手册。

6.2 Spring AI Alibaba 是什么

Spring AI Alibaba 是阿里开源的 Spring AI 生态扩展,面向国内企业场景,提供:

  • 通义千问等模型接入
  • RAG、向量库、工具调用增强
  • Nacos 集成:配置中心、服务注册发现
  • MCP 支持:Server 注册、Client 发现
  • 企业级治理能力:多租户、灰度、可观测

和 Spring AI 的关系:

text 复制代码
Spring AI(基础框架)
   └── Spring AI Alibaba(企业扩展)
        ├── 模型接入(通义等)
        ├── Nacos 注册发现
        ├── MCP 治理
        └── 可观测 / 网关

6.3 企业级 MCP 的痛点

单机 HTTP 模式(第 4 篇)在团队规模上来后会遇到:

痛点 说明
Server 地址散落 每个调用方手写 url,Server 迁移要全员改配置
鉴权分散 每个 Server 各做一套 token
无统一发现 新 Server 上线,调用方不知道
无灰度 升级只能全量切换
无统一审计 日志分散在各 Server
多租户难 不同团队权限、配额难隔离
Tool 级治理难 只按 URL 路由无法区分 sales_query 和 sales_export_csv

解法:注册中心 + 统一网关 + 治理平台。

6.4 目标架构

text 复制代码
┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ 调用方 A     │     │ 调用方 B     │     │ 调用方 C     │
│ Spring AI   │     │ 自研 Agent  │     │ Claude      │
└──────┬──────┘     └──────┬──────┘     └──────┬──────┘
       │                   │                   │
       └───────────────────┼───────────────────┘
                           │ HTTPS + Token
                    ┌──────▼──────┐
                    │ MCP Gateway │  统一鉴权、限流、路由、审计
                    └──────┬──────┘
                           │
          ┌────────────────┼────────────────┐
          │                │                │
   ┌──────▼──────┐  ┌──────▼──────┐  ┌──────▼──────┐
   │ sales-server│  │ hr-server   │  │finance-server│
   │  (HTTP)     │  │  (HTTP)     │  │  (HTTP)      │
   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘
          │                │                │
          └────────────────┼────────────────┘
                           │ 注册 / 发现
                    ┌──────▼──────┐
                    │   Nacos     │  配置中心 + 注册中心
                    └─────────────┘

📌 配图建议:发布时用 Draw.io 或 Excalidraw 把这张 ASCII 图重绘成精美拓扑图,标注数据流方向。

核心组件:

组件 职责
Nacos Server 注册、配置管理、动态下发
MCP Gateway 统一入口、鉴权、限流、路由、审计
各领域 Server 业务能力,HTTP 模式
调用方 Spring AI / 自研 Agent / Claude

6.5 Nacos 注册与发现

6.5.1 Server 注册

yaml 复制代码
spring:
  ai:
    mcp:
      server:
        name: sales-server
        version: 1.0.0
  cloud:
    nacos:
      discovery:
        server-addr: nacos.example.com:8848
        namespace: mcp-prod
        group: MCP_SERVERS

具体配置键以 Spring AI Alibaba 文档为准。

注册后,Nacos 中可见:

text 复制代码
服务名: sales-server
实例: 10.0.1.5:8080
元数据: { version: 1.0.0, tools: [sales_query, sales_top_regions] }

6.5.2 Client 发现

yaml 复制代码
spring:
  ai:
    mcp:
      client:
        nacos:
          enabled: true
          server-addr: nacos.example.com:8848
          service-name: sales-server

调用方代码不变,底层自动解析到可用实例。

6.5.3 Fallback:Nacos 挂了怎么办

🚨 企业级必须考虑的问题:注册中心不是永远可用的。Nacos 挂了,Client 是否能继续调用已知的 Server?

推荐三层 Fallback:

层 机制 说明
本地缓存 Client 缓存最近一次的实例列表 Nacos 不可达时用缓存,定期重试
静态配置兜底 application.yml 里保留一份静态 url 列表 缓存也没有时用静态配置
降级开关 配置中心下发"是否允许降级" 紧急时手动控制行为

Spring Cloud LoadBalancer + Nacos 通常自带本地缓存(spring.cloud.nacos.discovery.cache-enabled=true)。但 MCP Client 层是否缓存需要确认 SDK 实现,必要时自己加一层:

java 复制代码
public class ResilientMcpClientFactory {

    private final NacosServiceDiscovery nacos;
    private final Map<String, String> localCache = new ConcurrentHashMap<>();

    public String resolve(String serviceName) {
        try {
            String url = nacos.getInstance(serviceName).getUri();
            localCache.put(serviceName, url);
            return url;
        } catch (Exception e) {
            String cached = localCache.get(serviceName);
            if (cached != null) {
                log.warn("Nacos 不可达,使用本地缓存:{} -> {}", serviceName, cached);
                return cached;
            }
            throw new IllegalStateException("无法发现 " + serviceName + ",且无本地缓存");
        }
    }
}

💡 原则:注册中心是"加速器",不是"单点"。任何依赖注册中心的调用链,都要问一句"它挂了会怎样"。

6.6 MCP Gateway:统一入口

6.6.1 职责

text 复制代码
客户端 → Gateway → 按路径/服务名路由到对应 Server

Gateway 做:

  • 鉴权:统一校验 token,按调用方身份授权
  • 限流:按调用方、按 Server、按 Tool
  • 路由 :/sales/** → sales-server,/hr/** → hr-server
  • 审计:统一记录调用日志
  • 协议转换:SSE / Streamable HTTP 适配
  • 灰度:按版本分流

6.6.2 路由示例

text 复制代码
https://mcp.example.com/sales/mcp   → sales-server
https://mcp.example.com/hr/mcp      → hr-server
https://mcp.example.com/finance/mcp → finance-server

调用方只需要一个域名 + 一个 token,路径区分领域。

6.6.3 技术难点:MCP 网关不是普通 API 网关

🚨 这是最容易低估的地方。

普通 API 网关(Nginx、Spring Cloud Gateway)按 URL Path 路由和鉴权。但 MCP 的协议特点让它们不够用:

难点 说明
JSON-RPC 2.0 MCP 消息体是 JSON-RPC,tools/call 的 Tool 名在 body 里,不在 URL 里
长连接 SSE / Streamable HTTP 是长连接,传统网关的超时、缓冲、连接复用都要特殊处理
会话状态 SSE 有会话,多实例需要粘滞或共享会话
Tool 级治理 想限制"调用方 A 只能调 sales_query,不能调 sales_export_csv",网关必须解析 body

两种实现思路:

思路 A:网关解析 JSON-RPC(数据面治理)

text 复制代码
Gateway 收到 tools/call → 解析 body 得到 tool 名 → 查权限矩阵 → 放行/拒绝
  • 优点:Tool 级鉴权、限流、审计都在网关
  • 缺点:网关必须理解 MCP 协议,性能和复杂度上升,协议升级要跟

思路 B:控制面下发权限矩阵,数据面 Server 自校验(推荐)

text 复制代码
控制面(管理平台)→ 下发 token 对应的 Tool 权限矩阵给各 Server
Server 执行 Tool 前自校验 → 拒绝越权
Gateway 只做粗粒度路由和限流
  • 优点:Gateway 保持简单,Server 掌握细粒度权限
  • 缺点:权限逻辑分散在 Server,需要统一 SDK 或中间件约束

💡 落地建议:

  • 初期用思路 B:Gateway 做鉴权 + 限流 + 路由,Server 做 Tool 级权限。
  • 规模大了、治理要求高时,再评估思路 A 或混合方案。
  • 不要一上来就写一个"全知全能"的 MCP 网关,先跑通,再治理。

6.6.4 实现选型

方案 说明
Nginx / APISIX 通用网关,做路由、限流、鉴权前置;Tool 级需插件
Spring Cloud Gateway Java 生态,易扩展;可写 Filter 解析 JSON-RPC
自研 Gateway 需要 MCP 协议级治理时
Spring AI Alibaba 提供的集成 关注官方文档

6.7 企业治理能力

6.7.1 多租户

  • Nacos namespace 隔离环境(dev / test / prod)
  • 按租户分配 token,Gateway 校验租户与 Server 的授权关系
  • 配额按租户限制

6.7.2 版本与灰度

  • Server 注册时带 version 元数据
  • Gateway 按 header 或调用方配置分流到 v1 / v2
  • 新版本先小流量,观察成功率再全量

6.7.3 可观测

指标 说明
调用量 按 Server / Tool / 调用方
成功率 失败率、错误码分布
延迟 P50 / P95 / P99
限流触发 哪个调用方被限
工具触发准确率 模型是否选对 Tool
注册中心健康 Nacos 可达性、缓存命中率

统一上报到 Prometheus / OpenTelemetry,Grafana 看板。

6.7.4 审计

  • 谁调了什么 Tool、参数摘要、结果状态、耗时
  • 敏感参数脱敏
  • 日志集中存储,支持按调用方 / Server / 时间检索

6.8 代码骨架

6.8.1 Server 侧(Spring AI Alibaba)

java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class SalesServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SalesServerApplication.class, args);
    }
}
java 复制代码
@Component
public class SalesTools {

    private final SalesService service;

    public SalesTools(SalesService service) {
        this.service = service;
    }

    @Tool(name = "sales_query", description = "按地区和 ISO 周查询销售数据")
    public SalesRecord querySales(
            @ToolParam(description = "地区,例如 华东") String region,
            @ToolParam(description = "ISO 周,例如 2026-W20") String week) {
        return service.query(region, week);
    }
}
yaml 复制代码
spring:
  application:
    name: sales-server
  ai:
    mcp:
      server:
        name: sales-server
        version: 1.0.0
  cloud:
    nacos:
      discovery:
        server-addr: ${NACOS_ADDR}
        namespace: ${NACOS_NAMESPACE}
        group: MCP_SERVERS

6.8.2 Gateway 侧(Spring Cloud Gateway 示意)

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: sales
          uri: lb://sales-server
          predicates:
            - Path=/sales/**
        - id: hr
          uri: lb://hr-server
          predicates:
            - Path=/hr/**

鉴权、限流用 GlobalFilter 或 Spring Security 实现。Tool 级权限通过控制面下发到 Server,Server 侧自校验。

6.8.3 调用方(Spring AI Client)

yaml 复制代码
spring:
  ai:
    mcp:
      client:
        nacos:
          enabled: true
          server-addr: ${NACOS_ADDR}
          service-name: sales-server
java 复制代码
@RestController
public class ChatController {

    private final ChatClient chatClient;

    public ChatController(ChatClient.Builder builder,
                          ToolCallbackProvider mcpTools) {
        this.chatClient = builder.defaultTools(mcpTools).build();
    }

    @GetMapping("/chat")
    public String chat(@RequestParam String q) {
        return chatClient.prompt().user(q).call().content();
    }
}

6.9 适用场景与限制

6.9.1 适合

  • 多团队、多 Server 的企业环境
  • 需要统一鉴权、限流、审计
  • Server 频繁上下线、需要服务发现
  • 多环境、多租户隔离
  • 需要灰度和版本治理
  • 需要 Tool 级权限(配合思路 B)

6.9.2 不适合

  • 个人项目、单 Server
  • 没有 Nacos / 注册中心基础设施
  • 团队规模小,HTTP + token 已够用
  • 对 Spring AI Alibaba 版本稳定性要求高(仍在演进)
  • 没有能力维护一个"懂 MCP 协议"的网关(如果走思路 A)

6.9.3 落地建议

  1. 先用第 4 篇的 HTTP + token 跑通单 Server。
  2. Server 超过 3 个、调用方超过 3 个时,引入 Gateway。
  3. 需要动态发现和配置管理时,引入 Nacos,同时加本地缓存兜底。
  4. 需要 Tool 级治理时,优先"控制面下发权限矩阵 + Server 自校验"(思路 B)。
  5. 需要模型接入、RAG、工具编排时,引入 Spring AI Alibaba。
  6. 每一步都补鉴权、限流、审计,不要等规模大了再补。

6.10 本篇小结

  • 企业级 MCP 的痛点不是"能不能调",而是"怎么管"。
  • 架构:Nacos 注册发现 + MCP Gateway 统一入口 + 各领域 Server。
  • MCP 网关不是普通 API 网关:JSON-RPC body 里的 Tool 名、长连接、会话状态,让 Tool 级治理变复杂。
  • 推荐思路 B:Gateway 做粗粒度鉴权/限流/路由,Server 做 Tool 级权限自校验。
  • 注册中心不是单点:本地缓存 + 静态配置 + 降级开关三层兜底。
  • Spring AI Alibaba 提供 Nacos 集成和企业扩展,但版本仍在演进,落地要评估。
  • 从小规模 HTTP + token 起步,按需引入注册中心和网关。

系列总结

篇 解决什么 关键交付
1 认识 MCP 概念、架构、原语、传输、安全边界
2 本地单能力 Server java -jar + Claude Desktop 接入
3 多能力工程 多 Tool、多 Server、多 module、上下文膨胀数据
4 HTTP 对外服务 URL 拼接公式、Streamable HTTP、鉴权、Nginx SSE 配置
5 Spring AI 注解式 Tool、ChatClient、多模态返回
6 Spring AI Alibaba Nacos + Gateway + Tool 级治理难点 + Fallback

贯穿全系列的原则:

  1. 业务与协议解耦,Service 可单测。
  2. 输入必须校验,错误必须可读。
  3. Host 管"要不要调",Server 管"调了不出事"。
  4. stdio 日志走 stderr,HTTP 必须鉴权。
  5. 大结果集截断,摘要 + 下钻。
  6. 命名加领域前缀,多 Server 不冲突。
  7. 20 个 Tool 可能让准确率从 95% 掉到 70%,上下文要治理。
  8. URL = 域名 + context-path + endpoint,三部分缺一不可。
  9. 新项目优先 Streamable HTTP,SSE 是旧版。
  10. MCP 网关不是普通 API 网关,Tool 级治理要专门设计。
  11. 注册中心不是单点,必须有 Fallback。
  12. 对外服务用 HTTP,只给 url + token。
相关推荐
Light602 小时前
企业自建 AI 智能体,成本差 8 倍还是 46 倍?
java·人工智能·算法·知识图谱·rag·ai agent 上下文·token 成本
Wang's Blog2 小时前
Java 项目实战: 交友项目 - 阿里云 OSS 对象存储介绍
java·阿里云·交友
Yyyyyy~2 小时前
【Maven】基础
java·maven
weixin_BYSJ19872 小时前
【计算机毕设】基于Spring_Boot_Vue的马拉松报名与选手成绩追踪系统05445
java·vue.js·spring boot·学习·spring·django·课程设计
Shaoshing2 小时前
消息类型
java
2301_32241428042 小时前
springboot学生课堂出勤统计系统15835-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·mysql·随机森林·微信小程序·uni-app·微信开发者工具·推荐算法
程序员夏洛3 小时前
VMware Workstation Pro 卸载失败:安装向导提前结束、错误 1603 的排查与解决
java
User_芊芊君子3 小时前
【JavaEE初阶 - 网络原理】网络分几层?从自定义协议聊到 DNS
java·网络·java-ee
聚美智数10 小时前
智能结构化识别-图片结构解析-图像结构化解析-照片结构化解析
android·java·数据库