Spring AI 系列之三十一 - Spring AI Alibaba-基于Nacos的MCP

之前做个几个大模型的应用,都是使用Python语言,后来有一个项目使用了Java,并使用了Spring AI框架。随着Spring AI不断地完善,最近它发布了1.0正式版,意味着它已经能很好的作为企业级生产环境的使用。对于Java开发者来说真是一个福音,其功能已经能满足基于大模型开发企业级应用。借着这次机会,给大家分享一下Spring AI框架。

注意由于框架不同版本改造会有些使用的不同,因此本次系列中使用基本框架是 Spring AI-1.0.0,JDK版本使用的是19,Spring-AI-Alibaba-1.0.0.3-SNAPSHOT
代码参考: https://github.com/forever1986/springai-study

前几章基本上对Spring AI Alibaba的基本使用,包括模型、提示词、聊天记忆等讲了一遍,可以看到基本上使用方式与Spring AI差异不大,这一章讲一下Spring AI Alibaba-基于Nacos的MCP,这是一个基于企业级生产环境实践总结出来的应用框架。

1 基于Nacos的MCP

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

在这里插入图片描述

Nacos3中提供了新的MCP列表功能,其中有三类MCP服务可以注册到Nacos:

  • 第一类:已有的API服务,通过声明自动转化为 MCP 服务,配合 Higress 的协议转换能力,实现 0 代码改造成 MCP 服务协议
  • 第二类:已经构建好的或其他供应商提供的 MCP 服务,可以导入到 Nacos 中,进行其描述、工具列表、工具 Schema 等内容的动态修改和维护
  • 第三类:新构建的 MCP 服务注册, 配合 Spring AI Alibaba应用框架或者Nacos-MCP 的 sdk,能够做到像微服务一样自动注册到 Nacos 中进行统一的管理和维护

前两类都是Nacos3本身支持的功能,这里主要是讲Spring AI Alibaba。因此本次演示的是第三类,使用Spring AI Alibaba框架注册服务到Nacos,并通过Spring AI Alibaba框架获得及发现MCP服务。

2 MCP 服务注册到 Nacos

参考lesson25子模块中ali-mcp-server子模块

示例说明:本实例创建一个MCP的server,里面有一个查询天气的工具,然后将MCP服务(基于sse模式)注册到Nacos上面,本次使用Nacos3.0.2版本

2.1 前提准备

1)安装并启动nacos3.0.2

在这里插入图片描述
2)申请高德开放平台的API KEY

在这里插入图片描述

2.2 代码

1)新建lesson25子模块

2)在lesson25子模块下,新建ali-mcp-server子模块,其pom引入如下:

<dependencies>
    <!-- MCP Nacos 注册 -->
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-nacos-mcp-server</artifactId>
    </dependency>

    <!-- MCP Server (webflux) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
    </dependency>
</dependencies>

3)新建application.properties配置文件

server.port=9005
spring.application.name=mcp-nacos-registry-example

spring.ai.dashscope.api-key=你的阿里百炼API KEY
spring.ai.dashscope.chat.options.model=qwen-plus

## NacosMcpProperties nacos的配置
spring.ai.alibaba.mcp.nacos.namespace=public
spring.ai.alibaba.mcp.nacos.server-addr=localhost:8848
spring.ai.alibaba.mcp.nacos.username=nacos
spring.ai.alibaba.mcp.nacos.password=nacos

## McpServerProperties MCP的配置
spring.ai.mcp.server.name=webflux-mcp-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.type=ASYNC

## NacosMcpRegistryProperties MCP注册到nacos的配置
spring.ai.alibaba.mcp.nacos.registry.enabled=true
spring.ai.alibaba.mcp.nacos.registry.service-group=mcp-server
spring.ai.alibaba.mcp.nacos.registry.service-name=webflux-mcp-server

4)配置RestTemplateConfig类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

5)新增天气查询服务WeatherService:

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class WeatherService {

    @Autowired
    private RestTemplate restTemplate;

    private static final String adcode = "adcode";

    @Tool(description = "获取中国城市的天气情况")
    public String getWeatherForecastByCity(@ToolParam(description = "城市名称") String city) {
        // 获取城市的adcode
        String result = restTemplate.getForObject("https://restapi.amap.com/v3/geocode/geo?address="+city+"&key=ef3cbaef8f0965c6205f56e0ff00ceb4", String.class);
        // 这里为了方便简单处理一下字符串获取adcode,正式的话需要解析json格式
        int startIndex = result.indexOf(adcode);
        String code = result.substring(startIndex+adcode.length()+3,result.indexOf(",",startIndex)-1);
        // 通过城市的adcode,进行获取天气预报
        result = restTemplate.getForObject("https://restapi.amap.com/v3/weather/weatherInfo?extensions=all&key=ef3cbaef8f0965c6205f56e0ff00ceb4&city="+code, String.class);
        return result;
    }

}

6)新建启动类Lesson25ServerApplication,注册工具:

import com.demo.lesson25.server.service.WeatherService;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Lesson25ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(Lesson25ServerApplication.class, args);
    }

    @Bean
    public ToolCallbackProvider weatherTools(WeatherService weatherService) {
        return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
    }

}

2.3 演示

1)启动项目后,在nacos控制台的MCP服务列表可以看到注册的MCP服务

在这里插入图片描述

2)点击详情,可以看看详情

在这里插入图片描述

3)查看服务列表,可以看到服务已经注册到nacos

在这里插入图片描述

4)点击详情可以看到服务地址

在这里插入图片描述

3 Client 结合 Nacos 实现 MCP 集群发现

参考lesson25子模块中ali-mcp-client子模块

示例说明,本实例创建一个MCP的client,通过Nacos方式,将上面注册的工具通过sse模式拉取到本地,并访问测试

3.1 代码实现

1)在lesson25子模块下,新建ali-mcp-client子模块,其pom引入如下:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud.ai</groupId>
        <artifactId>spring-ai-alibaba-starter-nacos-mcp-client</artifactId>
    </dependency>
    <!-- 引入的是mcp-client -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
    </dependency>
</dependencies>

2)创建application.properties配置文件

server.port=9006
spring.application.name=mcp-nacos-client-example

spring.ai.dashscope.api-key=你的阿里百炼API KEY
spring.ai.dashscope.chat.options.model=qwen-plus

## NacosMcpProperties nacos的配置
spring.ai.alibaba.mcp.nacos.namespace=public
spring.ai.alibaba.mcp.nacos.server-addr=localhost:8848
spring.ai.alibaba.mcp.nacos.username=nacos
spring.ai.alibaba.mcp.nacos.password=nacos

## NacosMcpSseClientProperties MCP客户端配置通过nacos获取的MCP server
spring.ai.alibaba.mcp.nacos.client.enabled=true
spring.ai.alibaba.mcp.nacos.client.sse.connections.server1.service-name=webflux-mcp-server
spring.ai.alibaba.mcp.nacos.client.sse.connections.server1.version=1.0.0

## McpClientCommonProperties  MCP客户端配置的配置
spring.ai.mcp.client.enabled=true
spring.ai.mcp.client.name=mcp-client-webflux
spring.ai.mcp.client.version=1.0.0
spring.ai.mcp.client.type=ASYNC

3)配置ClientController 演示类:

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ClientController {

    private final ChatClient chatClient;


    public ClientController(ChatClient.Builder chatClientBuilder, @Qualifier("loadbalancedMcpAsyncToolCallbacks") ToolCallbackProvider tools) {
        this.chatClient = chatClientBuilder
                .defaultToolCallbacks(tools.getToolCallbacks())
                .build();
    }

    @GetMapping("/ai/generate")
    public String generate(@RequestParam(value = "message", defaultValue = "请问北京市目前天气预报?") String message) {
        return this.chatClient.prompt()
                .user(message)
                .call().content();
    }
}

说明:工具的获取,Spring AI Alibaba分为同步和异步
1)同步方式:

  • 通过@Qualifier(“loadbalancedSyncMcpToolCallbacks”) ToolCallbackProvider tools参数注册;
  • 通过@Autowired private List loadbalancedMcpSyncClients;变量注册

2)异步方式:

  • 通过@Qualifier(“loadbalancedMcpAsyncToolCallbacks”) ToolCallbackProvider tools参数注册;
  • 通过@Autowired private List loadbalancedMcpAsyncClients;变量注册

4)启动类Lesson25ClientApplication :

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Lesson25ClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(Lesson25ClientApplication.class, args);
    }

}

3.2 演示

http://localhost:9006/ai/generate

在这里插入图片描述

结语:本章通过一个基于Nacos的MCP服务端和MCP客户端,演示了Spring AI Alibaba-基于Nacos的MCP实现方法,当然Spring AI Alibaba-基于Nacos的MCP是一种企业级的应用模式,详情可以参考官方文档,它并不止提供本章内容,比如远程其它MCP服务也可以通过Nacos注册等等。这里就不多累述。

Spring AI系列上一章:《Spring AI 系列之三十 - Spring AI Alibaba-其它模型

Spring AI系列下一章:《Spring AI 系列之三十二 - Spring AI Alibaba-Graph框架之入门

### 集成方法 在集成 Spring AI Alibaba MCP 时,首先需要确保项目具备必要的依赖。例如,通过在 `pom.xml` 文件中添加 `spring-ai-alibaba-starter` 和 `spring-ai-mcp-client-spring-boot-starter` 依赖,可以快速引入 Spring AI AlibabaMCP 客户端的支持[^4]。 ```xml <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-starter</artifactId> <version>1.0.0-M6.1</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId> <version>1.0.0-M6</version> </version> ``` 此外,还需要配置 Nacos 服务器以支持 MCP 服务的注册与发现。可以通过 Docker 启动 Nacos 并验证其运行状态。随后,在 Nacos 控制台中创建配置文件,用于管理 MCP 服务的元数据和工具描述[^3]。 ### 最佳实践 在使用 Spring AI Alibaba MCP 时,遵循一些最佳实践可以提高开发效率和系统稳定性。首先是配置管理的最佳实践,包括环境隔离和配置版本管理。通过 Nacos 的命名空间和分组功能,可以有效地隔离不同环境下的配置,如开发、测试和生产环境。同时,利用 Nacos 的版本管理功能,可以追踪配置的变化历史,便于回滚和调试[^3]。 性能优化方面,可以通过缓存策略和连接池配置来提升 MCP 服务的响应速度和吞吐量。例如,对于频繁调用的 MCP 工具,可以启用缓存以减少重复请求;而对于数据库或其他外部服务的连接,则应配置合适的连接池参数,以避免资源耗尽。 监控和日志也是不可或缺的一部分。通过自定义监控指标,可以实时跟踪 MCP 服务的运行状态,及时发现并解决问题。Spring Boot Actuator 提供了丰富的监控端点,可以方便地集成到项目中。此外,启用详细日志记录可以帮助开发者更好地理解服务的执行流程,特别是在调试复杂问题时非常有用。 ### 相关问题 1. 如何在 Spring Boot 项目中配置 Nacos 以支持 MCP 服务? 2. 在 Spring AI Alibaba 中如何实现 MCP 工具的缓存策略? 3. 如何通过 Spring Boot Actuator 监控 MCP 服务的运行状态?
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linmoo2006

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值