当前位置: 首页 > ai >正文

Spring AI Alibaba Nacos 集成实践

文章目录

    • 🎯 基础理论
      • 什么是 Spring AI Alibaba Nacos 集成?
      • 核心组件架构
    • 🛠️ 环境搭建
      • 1. 前置条件
      • 2. 启动 Nacos 服务器
        • 使用 Docker 启动 Nacos
        • 验证 Nacos 启动
      • 3. 项目依赖配置
    • 📝 Nacos Prompt 模板管理
      • 1. 基础配置
      • 2. 在 Nacos 中配置 Prompt 模板
        • 步骤 1:登录 Nacos 控制台
        • 步骤 2:创建配置
      • 3. Java 代码实现
        • 创建 Prompt 服务类
        • 创建控制器
      • 4. 测试 Prompt 模板
        • 启动应用
        • 测试接口
    • 🔌 Nacos MCP 客户端
      • 1. MCP 客户端配置
      • 2. 创建 MCP 客户端服务
      • 3. 创建 MCP 控制器
    • 🖥️ Nacos MCP 服务端
      • 1. 创建 MCP 服务端项目
        • 添加依赖
        • 配置文件
      • 2. 实现 MCP 工具
        • 天气查询工具
        • 计算器工具
      • 3. 启动类
    • 🌐 Nacos MCP 网关
      • 1. 网关配置
      • 2. 在 Nacos 中配置服务模板
    • 🚀 实战项目
      • 项目:智能客服系统
        • 1. 项目结构
        • 2. 主应用实现
        • 3. 在 Nacos 中配置客服模板
    • 📋 最佳实践
      • 1. 配置管理最佳实践
        • 环境隔离
        • 配置版本管理
      • 2. 性能优化
        • 缓存策略
        • 连接池配置
      • 3. 监控和日志
        • 自定义监控指标
    • 🔧 故障排除
      • 常见问题及解决方案
        • 1. Nacos 连接失败
        • 2. Prompt 模板加载失败
        • 3. MCP 服务发现问题
      • 调试技巧
        • 1. 启用详细日志
        • 2. 使用 Actuator 监控
    • 📚 参考资料

🎯 基础理论

什么是 Spring AI Alibaba Nacos 集成?

Spring AI Alibaba 与 Nacos 的集成提供了以下核心功能:

  1. Prompt 模板管理:通过 Nacos 配置中心动态管理 AI 提示词模板
  2. MCP 服务发现:基于 Nacos 的 MCP (Model Context Protocol) 服务注册与发现
  3. 动态配置:实时更新 AI 相关配置,无需重启应用
  4. 负载均衡:支持 MCP 服务的负载均衡和故障转移

核心组件架构

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   AI 应用       │    │   Nacos 服务    │    │   MCP 服务      │
│                 │    │                 │    │                 │
│ ┌─────────────┐ │    │ ┌─────────────┐ │    │ ┌─────────────┐ │
│ │Prompt模板   │◄┼────┼►│配置中心     │ │    │ │工具服务     │ │
│ └─────────────┘ │    │ └─────────────┘ │    │ └─────────────┘ │
│ ┌─────────────┐ │    │ ┌─────────────┐ │    │ ┌─────────────┐ │
│ │MCP客户端    │◄┼────┼►│服务注册中心 │◄┼────┼►│服务注册     │ │
│ └─────────────┘ │    │ └─────────────┘ │    │ └─────────────┘ │
└─────────────────┘    └─────────────────┘    └─────────────────┘

🛠️ 环境搭建

1. 前置条件

  • Java 17+
  • Maven 3.6+
  • Nacos Server 2.x 或 3.x
  • Spring Boot 3.x

2. 启动 Nacos 服务器

使用 Docker 启动 Nacos
# 启动 Nacos 容器
docker run -d \--name nacos-server \-p 8848:8848 \-p 9848:9848 \-e MODE=standalone \nacos/nacos-server:v2.3.0
验证 Nacos 启动

访问 Nacos 控制台:http://localhost:8848/nacos

  • 用户名:nacos
  • 密码:nacos

3. 项目依赖配置

创建基础的 Spring Boot 项目,添加以下依赖:

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring AI Alibaba Core --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId><version>1.0.0-M8.1-SNAPSHOT</version></dependency><!-- Nacos Prompt 模板支持 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-nacos-prompt</artifactId><version>1.0.0-M8.1-SNAPSHOT</version></dependency><!-- Nacos MCP 客户端支持 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-nacos-mcp-client</artifactId><version>1.0.0-M8.1-SNAPSHOT</version></dependency>
</dependencies>

📝 Nacos Prompt 模板管理

1. 基础配置

application.yml 中配置 Nacos 连接信息:

spring:ai:nacos:prompt:template:enabled: true  # 启用 Nacos Prompt 模板alibaba:nacos:server-addr: localhost:8848username: nacospassword: nacosnamespace: public

2. 在 Nacos 中配置 Prompt 模板

步骤 1:登录 Nacos 控制台

访问 http://localhost:8848/nacos,使用 nacos/nacos 登录。

步骤 2:创建配置

在「配置管理」→「配置列表」中,点击「+」创建新配置:

  • Data ID: ai-prompt-templates
  • Group: DEFAULT_GROUP
  • 配置格式: YAML
  • 配置内容:
templates:greeting:content: "你好,{name}!欢迎使用 Spring AI Alibaba。"description: "问候语模板"variables:- name: "name"type: "string"required: truedescription: "用户姓名"code-review:content: |请对以下代码进行审查:```{language}{code}```请从以下方面进行分析:1. 代码质量2. 性能优化建议3. 安全性考虑4. 最佳实践建议description: "代码审查模板"variables:- name: "language"type: "string"required: truedescription: "编程语言"- name: "code"type: "string"required: truedescription: "待审查的代码"

3. Java 代码实现

创建 Prompt 服务类
package com.example.demo.service;import com.alibaba.cloud.ai.prompt.ConfigurablePromptTemplateFactory;
import org.springframework.ai.prompt.PromptTemplate;
import org.springframework.stereotype.Service;import java.util.Map;@Service
public class PromptService {private final ConfigurablePromptTemplateFactory promptTemplateFactory;public PromptService(ConfigurablePromptTemplateFactory promptTemplateFactory) {this.promptTemplateFactory = promptTemplateFactory;}/*** 获取问候语*/public String getGreeting(String name) {PromptTemplate template = promptTemplateFactory.create("greeting");return template.render(Map.of("name", name));}/*** 获取代码审查提示词*/public String getCodeReviewPrompt(String language, String code) {PromptTemplate template = promptTemplateFactory.create("code-review");return template.render(Map.of("language", language,"code", code));}
}
创建控制器
package com.example.demo.controller;import com.example.demo.service.PromptService;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/prompt")
public class PromptController {private final PromptService promptService;public PromptController(PromptService promptService) {this.promptService = promptService;}@GetMapping("/greeting")public String greeting(@RequestParam String name) {return promptService.getGreeting(name);}@PostMapping("/code-review")public String codeReview(@RequestBody CodeReviewRequest request) {return promptService.getCodeReviewPrompt(request.language(), request.code());}public record CodeReviewRequest(String language, String code) {}
}

4. 测试 Prompt 模板

启动应用
mvn spring-boot:run
测试接口
# 测试问候语
curl "http://localhost:8080/api/prompt/greeting?name=张三"# 测试代码审查
curl -X POST "http://localhost:8080/api/prompt/code-review" \-H "Content-Type: application/json" \-d '{"language": "java","code": "public class Hello { public static void main(String[] args) { System.out.println(\"Hello World\"); } }"}'

🔌 Nacos MCP 客户端

1. MCP 客户端配置

application.yml 中添加 MCP 客户端配置:

spring:ai:alibaba:mcp:nacos:server-addr: localhost:8848username: nacospassword: nacosnamespace: publicclient:sse:connections:weather-service:service-name: weather-mcp-serverversion: 1.0.0calculator-service:service-name: calculator-mcp-serverversion: 1.0.0

2. 创建 MCP 客户端服务

package com.example.demo.service;import com.alibaba.cloud.ai.mcp.nacos.client.transport.LoadbalancedMcpSyncClient;
import org.springframework.ai.mcp.client.McpSyncClient;
import org.springframework.ai.mcp.spec.McpSchema;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Map;@Service
public class McpClientService {private final LoadbalancedMcpSyncClient mcpClient;public McpClientService(LoadbalancedMcpSyncClient mcpClient) {this.mcpClient = mcpClient;}/*** 获取可用的工具列表*/public List<McpSchema.Tool> getAvailableTools() {return mcpClient.listTools().tools();}/*** 调用天气查询工具*/public String getWeather(String city) {var request = McpSchema.CallToolRequest.builder().name("get_weather").arguments(Map.of("city", city)).build();var response = mcpClient.callTool(request);return response.content().get(0).text();}/*** 调用计算器工具*/public String calculate(String expression) {var request = McpSchema.CallToolRequest.builder().name("calculate").arguments(Map.of("expression", expression)).build();var response = mcpClient.callTool(request);return response.content().get(0).text();}
}

3. 创建 MCP 控制器

package com.example.demo.controller;import com.example.demo.service.McpClientService;
import org.springframework.ai.mcp.spec.McpSchema;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/api/mcp")
public class McpController {private final McpClientService mcpClientService;public McpController(McpClientService mcpClientService) {this.mcpClientService = mcpClientService;}@GetMapping("/tools")public List<McpSchema.Tool> getTools() {return mcpClientService.getAvailableTools();}@GetMapping("/weather")public String getWeather(@RequestParam String city) {return mcpClientService.getWeather(city);}@GetMapping("/calculate")public String calculate(@RequestParam String expression) {return mcpClientService.calculate(expression);}
}

🖥️ Nacos MCP 服务端

1. 创建 MCP 服务端项目

添加依赖
<dependencies><!-- MCP 服务端支持 --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-nacos-mcp-server</artifactId><version>1.0.0-M8.1-SNAPSHOT</version></dependency><!-- WebFlux 支持 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webflux</artifactId><version>1.0.0-M8</version></dependency>
</dependencies>
配置文件
spring:ai:alibaba:mcp:nacos:server-addr: localhost:8848username: nacospassword: nacosnamespace: publicregistry:service-register: trueservice-name: weather-mcp-serverservice-version: 1.0.0service-group: DEFAULT_GROUPserver:port: 8081

2. 实现 MCP 工具

天气查询工具
package com.example.weather.tools;import org.springframework.ai.mcp.server.McpAsyncFunction;
import org.springframework.ai.mcp.spec.McpSchema;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;@Component
public class WeatherTool implements McpAsyncFunction {@Overridepublic String getName() {return "get_weather";}@Overridepublic String getDescription() {return "获取指定城市的天气信息";}@Overridepublic McpSchema.ToolInputSchema getInputSchema() {return McpSchema.ToolInputSchema.builder().type("object").properties(Map.of("city", Map.of("type", "string","description", "城市名称"))).required(List.of("city")).build();}@Overridepublic CompletableFuture<List<McpSchema.TextContent>> apply(Map<String, Object> arguments) {String city = (String) arguments.get("city");// 模拟天气查询String weatherInfo = getWeatherInfo(city);var content = McpSchema.TextContent.builder().type("text").text(weatherInfo).build();return CompletableFuture.completedFuture(List.of(content));}private String getWeatherInfo(String city) {// 这里可以调用真实的天气 APIreturn String.format("{
" +"  \"city\": \"%s\",
" +"  \"temperature\": \"22°C\",
" +"  \"weather\": \"晴天\",
" +"  \"humidity\": \"65%%\",
" +"  \"wind\": \"东南风 3级\"
" +"}", city);}
}
计算器工具
package com.example.weather.tools;import org.springframework.ai.mcp.server.McpAsyncFunction;
import org.springframework.ai.mcp.spec.McpSchema;
import org.springframework.stereotype.Component;import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;@Component
public class CalculatorTool implements McpAsyncFunction {private final ScriptEngine scriptEngine;public CalculatorTool() {this.scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");}@Overridepublic String getName() {return "calculate";}@Overridepublic String getDescription() {return "执行数学计算";}@Overridepublic McpSchema.ToolInputSchema getInputSchema() {return McpSchema.ToolInputSchema.builder().type("object").properties(Map.of("expression", Map.of("type", "string","description", "数学表达式,如:2+3*4"))).required(List.of("expression")).build();}@Overridepublic CompletableFuture<List<McpSchema.TextContent>> apply(Map<String, Object> arguments) {String expression = (String) arguments.get("expression");try {Object result = scriptEngine.eval(expression);var content = McpSchema.TextContent.builder().type("text").text("计算结果:" + expression + " = " + result).build();return CompletableFuture.completedFuture(List.of(content));} catch (Exception e) {var content = McpSchema.TextContent.builder().type("text").text("计算错误:" + e.getMessage()).build();return CompletableFuture.completedFuture(List.of(content));}}
}

3. 启动类

package com.example.weather;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class WeatherMcpServerApplication {public static void main(String[] args) {SpringApplication.run(WeatherMcpServerApplication.class, args);}
}

🌐 Nacos MCP 网关

MCP 网关提供了动态代理功能,可以将 Nacos 中注册的服务转换为 MCP 协议服务。

1. 网关配置

spring:ai:alibaba:mcp:nacos:server-addr: localhost:8848username: nacospassword: nacosnamespace: publicdynamic:service-namespace: publicservice-group: DEFAULT_GROUPservice-names:- weather-service- calculator-serviceserver:port: 8082

2. 在 Nacos 中配置服务模板

在 Nacos 控制台中创建配置:

  • Data ID: weather-service-mcp-template
  • Group: DEFAULT_GROUP
  • 配置内容:
{"tools": [{"name": "get_weather","description": "获取天气信息","inputSchema": {"type": "object","properties": {"city": {"type": "string","description": "城市名称"}},"required": ["city"]},"requestTemplate": {"url": "/api/weather?city={{.args.city}}","method": "GET"},"responseTemplate": {"body": "天气信息:{{.response.body}}"}}]
}

🚀 实战项目

项目:智能客服系统

我们将创建一个完整的智能客服系统,集成所有 Nacos 功能。

1. 项目结构
intelligent-customer-service/
├── customer-service-app/          # 主应用
├── weather-mcp-server/           # 天气服务
├── knowledge-mcp-server/         # 知识库服务
├── mcp-gateway/                  # MCP 网关
└── docker-compose.yml            # 容器编排
2. 主应用实现
package com.example.customerservice.service;import com.alibaba.cloud.ai.prompt.ConfigurablePromptTemplateFactory;
import com.example.customerservice.mcp.McpClientService;
import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Service;import java.util.Map;@Service
public class CustomerServiceBot {private final ChatClient chatClient;private final ConfigurablePromptTemplateFactory promptFactory;private final McpClientService mcpClientService;public CustomerServiceBot(ChatClient chatClient, ConfigurablePromptTemplateFactory promptFactory,McpClientService mcpClientService) {this.chatClient = chatClient;this.promptFactory = promptFactory;this.mcpClientService = mcpClientService;}public String handleCustomerQuery(String query, String customerName) {// 1. 使用 Nacos 中的 prompt 模板var promptTemplate = promptFactory.create("customer-service");// 2. 根据查询类型调用相应的 MCP 服务String contextInfo = "";if (query.contains("天气")) {contextInfo = mcpClientService.getWeather(extractCity(query));} else if (query.contains("计算")) {contextInfo = mcpClientService.calculate(extractExpression(query));}// 3. 构建完整的提示词String fullPrompt = promptTemplate.render(Map.of("customerName", customerName,"query", query,"contextInfo", contextInfo));// 4. 调用 AI 模型生成回复return chatClient.call(new Prompt(fullPrompt)).getResult().getOutput().getContent();}private String extractCity(String query) {// 简单的城市提取逻辑return "北京"; // 实际应用中需要更复杂的 NLP 处理}private String extractExpression(String query) {// 简单的表达式提取逻辑return "2+3"; // 实际应用中需要更复杂的解析}
}
3. 在 Nacos 中配置客服模板
templates:customer-service:content: |你是一个专业的客服助手,正在为客户 {customerName} 提供服务。客户问题:{query}相关信息:{contextInfo}请根据以上信息,用友好、专业的语气回复客户。如果需要更多信息,请礼貌地询问。回复要求:1. 语气友好、专业2. 回答准确、有用3. 如果无法解答,请引导客户联系人工客服description: "客服回复模板"variables:- name: "customerName"type: "string"required: true- name: "query"type: "string"required: true- name: "contextInfo"type: "string"required: false

📋 最佳实践

1. 配置管理最佳实践

环境隔离
# 开发环境
spring:profiles:active: devai:nacos:prompt:template:enabled: truealibaba:nacos:server-addr: dev-nacos:8848namespace: dev---
# 生产环境
spring:profiles: prodai:alibaba:nacos:server-addr: prod-nacos:8848namespace: prod
配置版本管理
@Component
public class PromptVersionManager {private final ConfigurablePromptTemplateFactory promptFactory;public PromptVersionManager(ConfigurablePromptTemplateFactory promptFactory) {this.promptFactory = promptFactory;}public String getPromptWithFallback(String templateName, String version) {try {// 尝试获取指定版本的模板return promptFactory.create(templateName + "_v" + version).getTemplate();} catch (Exception e) {// 回退到默认版本return promptFactory.create(templateName).getTemplate();}}
}

2. 性能优化

缓存策略
@Service
public class CachedPromptService {private final ConfigurablePromptTemplateFactory promptFactory;private final Cache<String, PromptTemplate> templateCache;public CachedPromptService(ConfigurablePromptTemplateFactory promptFactory) {this.promptFactory = promptFactory;this.templateCache = Caffeine.newBuilder().maximumSize(100).expireAfterWrite(Duration.ofMinutes(10)).build();}public PromptTemplate getTemplate(String name) {return templateCache.get(name, key -> promptFactory.create(key));}
}
连接池配置
spring:ai:alibaba:nacos:# 连接池配置pool:max-active: 20max-idle: 10min-idle: 5max-wait: 5000

3. 监控和日志

自定义监控指标
@Component
public class NacosMetrics {private final MeterRegistry meterRegistry;private final Counter promptLoadCounter;private final Timer mcpCallTimer;public NacosMetrics(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;this.promptLoadCounter = Counter.builder("nacos.prompt.load").description("Prompt template load count").register(meterRegistry);this.mcpCallTimer = Timer.builder("nacos.mcp.call").description("MCP service call duration").register(meterRegistry);}public void recordPromptLoad(String templateName) {promptLoadCounter.increment(Tags.of("template", templateName));}public void recordMcpCall(String serviceName, Duration duration) {mcpCallTimer.record(duration, Tags.of("service", serviceName));}
}

🔧 故障排除

常见问题及解决方案

1. Nacos 连接失败

问题:应用启动时无法连接到 Nacos 服务器

解决方案

# 检查 Nacos 服务状态
curl http://localhost:8848/nacos/v1/ns/operator/metrics# 检查网络连通性
telnet localhost 8848# 查看应用日志
tail -f logs/spring.log | grep nacos
2. Prompt 模板加载失败

问题:提示词模板无法从 Nacos 加载

解决方案

@Component
public class PromptHealthChecker {@EventListenerpublic void onApplicationReady(ApplicationReadyEvent event) {try {// 验证关键模板是否可用promptFactory.create("customer-service");log.info("Prompt templates loaded successfully");} catch (Exception e) {log.error("Failed to load prompt templates", e);// 可以选择使用本地备份模板}}
}
3. MCP 服务发现问题

问题:MCP 客户端无法发现服务

解决方案

@Component
public class McpServiceHealthChecker {@Scheduled(fixedRate = 30000) // 每30秒检查一次public void checkMcpServices() {try {List<McpSchema.Tool> tools = mcpClientService.getAvailableTools();log.info("Available MCP tools: {}", tools.size());} catch (Exception e) {log.warn("MCP service check failed", e);}}
}

调试技巧

1. 启用详细日志
logging:level:com.alibaba.cloud.ai: DEBUGcom.alibaba.nacos: DEBUGorg.springframework.ai.mcp: DEBUG
2. 使用 Actuator 监控
management:endpoints:web:exposure:include: health,info,metrics,nacosendpoint:health:show-details: always

📚 参考资料

  • Spring AI Alibaba 官方文档
  • Nacos 官方文档
  • MCP 协议规范
  • Spring AI 文档
http://www.xdnf.cn/news/14691.html

相关文章:

  • 【C++ 基础】 C++ 与 C 语言差异面试题(附大厂真题解析)
  • 【智能协同云图库】智能协同云图库第三弹:基于腾讯云 COS 对象存储—开发图片模块
  • 【Linux高级全栈开发】2.3.1 协程设计原理与汇编实现2.3.2 协程调度器实现与性能测试
  • 原型设计Axure RP网盘资源下载与安装教程共享
  • 【记录】服务器多用户共享Conda环境——Ubuntu24.04
  • 进阶向:Django入门,从零开始构建一个Web应用
  • Word之电子章制作——1
  • kubectl exec 原理
  • 力扣第73题-矩阵置零
  • Flutter基础(Children|​​Actions|Container|decoration|child)
  • git使用详解和示例
  • 【区块链】区块链交易(Transaction)之nonce
  • 【Docker基础】Docker容器管理:docker stats及其参数详解
  • C++共享型智能指针std::shared_ptr使用介绍
  • 机器学习配置环境
  • 某音Web端消息体ProtoBuf结构解析
  • 力扣 刷题(第七十一天)
  • 第七章——一元函数微分学的物理应用
  • 多表连接查询:语法、注意事项与最佳实践
  • 如何快速学习一门新编程语言
  • 【Linux】理解进程状态与优先级:操作系统中的调度原理
  • STM32HAL 旋转编码器教程
  • 自定义上下两个方向的柱形图
  • Vue.js 中的数字格式化组件:`FormattedNumber`
  • Note2.4 机器学习:Batch Normalization Introduction
  • 栅极驱动器选的好SiC MOSFET高效又安全
  • Microsoft AZ-900AI-900考证速过经验分享
  • docker部署后端服务的脚本
  • 大模型在急性冠脉综合征预测及诊疗方案制定中的应用研究
  • 大数据在UI前端的应用创新研究:用户偏好的动态调整与优化