使用 Spring AI Alibaba MCP 结合 Nacos 实现企业级智能体应用

在上一篇《Spring AI Alibaba MCP 协议的全链路安全与动态鉴权》中,我们解决了 AI 应用"裸奔"的问题,实现了通道层的 Token 透传与服务层的准入控制。然而,在真实的生产环境中,仅仅实现"能用"是远远不够的。企业级智能体应用必须面对高并发、高可用的挑战。

现阶段,如果 MCP Client 和 MCP Server 保持简单的一对一连接,一旦 MCP Server 节点宕机,Client 端将瞬间失去工具调用能力,这在企业级场景中是不可接受的。本文将深入探讨如何利用 Nacos 服务注册中心 ,为 Spring AI Alibaba MCP 构建一套分布式智能体应用架构,实现服务的动态发现、负载均衡与高可用容错。

Spring AI Alibaba MCP 结合 Nacos 服务注册中心,为企业级智能体应用提供了强大的基础架构支持。这一组合解决方案主要围绕三条核心技术线展开,实现了从服务注册、工具代理到服务发现的完整闭环:

  1. 服务注册:将 MCP Server 的元信息(地址、能力、版本)注册到 Nacos,实现服务能力的中央化管理。
  2. 服务发现:MCP Client 从 Nacos 动态获取可用的 Server 列表,摒弃硬编码的 IP 地址。
  3. 分布式治理:实现流量的负载均衡、节点变更的动态感知以及故障剔除。

在默认的 MCP 调用模式下,Client 通常直接绑定一个固定的 Server 地址。

  • 风险:若当前 MCP Server 挂掉了,MCP Client 便不能使用其提供的工具能力,工具稳定性的提供得不到保证。
  • 解决方案 :我们引入 DistributedSyncMcpClient。它允许一个 MCP Client 端连接多个 MCP Server(分布式部署)。通过监听机制,动态应对 MCP Server 节点的上下线,并调整 Server 列表。

设计思路:

  • 读操作(如获取工具列表):采用负载均衡策略(如随机、轮询),从可用列表中选取一个节点发起请求。
  • 写操作(如修改 Server 状态):需要广播或一致性协议,修改所有的 MCP Server(本文主要聚焦于读场景的高可用)。

MCP Server 端改造:接入 Nacos 注册中心

1. 引入依赖

pom.xml 中添加 Spring Cloud Alibaba AI 的 Nacos 注册中心支持依赖:

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-mcp-registry</artifactId>
    <version>1.1.2.2</version>
</dependency>

2. 配置 Nacos 信息

application.yml 中配置 Nacos 地址及注册信息:

yaml 复制代码
spring:
  application:
    name: mcp-nacos-register-extensions-example
  ai:
    mcp:
      server:
        protocol: sse
        name: mcp-server
        version: 1.0.0
        # ... 其他 Server 配置保持不变
      alibaba:
        mcp:
          nacos:
            namespace: 0178b20f-f8c5-4182-9d41-f744f6328c48 # 你的命名空间ID
            server-addr: 192.168.0.201:8848
            username: nacos
            password: z123
            register:
              enabled: true
              service-group: mcp-server
              service-name: mcp-server # 注册到 Nacos 的服务名

3. 效果验证

启动应用后,访问 Nacos 控制台。你应该能看到 mcp-server 已经成功注册,且包含了 MCP 协议特有的元数据(如支持的 Tools 列表等)。


再启动一个MCPServer,端口不同,其他不变,观察Nacos控制台:

MCP Client 端改造:构建分布式连接

Client 端是本次改造的核心。我们需要让 Client 从 Nacos 拉取服务列表,并构建分布式连接池。
1. 引入依赖

除了核心的 MCP 依赖,我们需要引入分布式支持模块和 JSON Schema 校验器(用于工具定义解析):

xml 复制代码
<dependency>
    <groupId>com.alibaba.cloud.ai</groupId>
    <artifactId>spring-ai-alibaba-starter-mcp-distributed</artifactId>
    <version>1.1.2.2</version>
</dependency>
<dependency>
    <groupId>com.networknt</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>3.0.1</version>
</dependency>

2. 配置分布式连接

application.yml 中,我们不再配置固定的 URL,而是配置 Nacos 地址和要订阅的服务名:

yaml 复制代码
spring:
  ai:
    alibaba:
      mcp:
        nacos:
          client:
            enabled: true
            sse:
              connections:
                server1: # 连接别名
                  service-name: mcp-server # 对应 Nacos 中注册的服务名
                  version: 1.0.0
            configs:
              server1:
                namespace: 0178b20f-f8c5-4182-9d41-f744f6328c48
                server-addr: 192.168.0.201:8848
                username: nacos
                password: z123

3. 代码调用

使用 distributedSyncToolCallback 来获取工具列表,这是分布式场景下的标准入口:

java 复制代码
@Bean
public CommandLineRunner predefinedQuestions(
    ChatClient.Builder chatClientBuilder,
    @Qualifier("distributedSyncToolCallback") ToolCallbackProvider tools, // 使用分布式 Provider
    ConfigurableApplicationContext context) {
}

深度整合:分布式场景下的鉴权续命

场景复现:

在上一篇博客中,我们通过自定义 McpSyncHttpClientRequestCustomizer 注入 Token。但是,结合 Nacos 后,请求的发起逻辑变了。底层不再直接使用我们配置的普通 Client,而是使用了 WebClient.Builder

源码分析:

通过阅读 SseWebFluxDistributedSyncMcpClient 源码的 clientByEndpoint 方法(第 104-116 行),我们可以看到:

java 复制代码
WebClient.Builder webClientBuilder = this.webClientBuilderTemplate.clone().baseUrl(baseUrl);

它使用了自动注入的 webClientBuilderTemplate。这意味着,McpAsyncHttpClientRequestCustomizer 的逻辑在这里失效了。

解决方案:

既然底层是 WebClient,我们不需要去覆盖复杂的 DistributedSyncMcpClient,只需要提供一个带有默认 Header 的 WebClient.Builder Bean 即可。Spring AI Alibaba 的自动配置会自动使用这个 Bean。

实现代码:

java 复制代码
@Bean
public WebClientCustomizer webClientCustomizer() {
    return webClientBuilder -> webClientBuilder
            .defaultHeader("token-1", "yingzi-1") // 注入上一篇的 Token
            .defaultHeader("token-2", "yingzi-2");
}

原理:
WebClientCustomizer 是 Spring 提供的回调接口。当 Spring 容器中存在该 Bean 时,它会在自动配置创建 WebClient.Builder 之后对其进行"二次加工"。我们设置的默认请求头会合并到最终发出的 HTTP 请求中,完美解决了分布式场景下的鉴权问题。

总结

通过本文的实战,我们完成了从单体 MCP 应用到企业级分布式智能体应用的跨越:

  1. 架构升级:利用 Nacos 实现了 MCP Server 的服务注册与发现,解决了硬编码问题。
  2. 高可用 :通过 DistributedSyncMcpClient 实现了多节点的负载均衡,消除了单点故障(SPOF)。
  3. 安全延续 :通过定制 WebClient.Builder,在分布式架构中无缝保留了上一篇的 Token 鉴权机制。

分布式调用效果图



我们观察效果图发现分别调用了两个Server不同的工具,实现了默认的轮训效果。

目前的方案已经解决了基础的高可用问题。在后续的篇章中,我们将探索如何结合 Spring AI Alibaba MCP Gateway 为普通应用建立一个中间代理层 Java MCP 应用,实现将 Restful接口 无缝转换成 MCPServer

相关推荐
海兰8 分钟前
【实战】HiMarket本地化部署指南
人工智能·ubuntu·架构·银行系统
zhangshuang-peta10 分钟前
MCP:把不确定性变成工程能力
人工智能·ai agent·mcp·peta
m0_5648768421 分钟前
提示词工程手册学习
人工智能·python·深度学习·学习
AlunYegeer26 分钟前
MyBatis 传参核心:#{ } 与 ${ } 区别详解(避坑+面试重点)
java·mybatis
少许极端38 分钟前
算法奇妙屋(四十)-贪心算法学习之路7
java·学习·算法·贪心算法
危笑ioi39 分钟前
helm部署skywalking链路追踪 java
java·开发语言·skywalking
AI精钢1 小时前
谷歌时隔一年发布“更加开源“的 Gemma 4,意图何为?
人工智能·云原生·开源·aigc
夕除1 小时前
Mysql--15
java·数据库·mysql
smileNicky1 小时前
Linux 系列从多节点的catalina 日志中统计设备调用频次
java·linux·服务器
洞见新研社1 小时前
从算力到电力,谁在搭建AI时代的“能源基座”?
人工智能·能源