1. 项目概述作为一名长期奋战在Java开发一线的工程师我深知Java开发者在AI浪潮中的尴尬处境。每当想要尝试大模型应用铺天盖地的Python教程总让人望而却步。直到我发现OllamaSpring Boot这套组合拳终于让Java开发者也能轻松玩转本地大模型部署。本文将详细介绍如何在本地环境部署阿里通义千问Qwen 3.5大模型并通过Spring Boot 3.x实现Java后端集成。整个过程完全不需要Python环境8GB显存即可流畅运行9B参数模型5行核心代码就能实现AI对话功能。2. 环境准备与工具选型2.1 硬件需求分析很多开发者对本地运行大模型存在误解认为必须配备顶级显卡。实际上Qwen 3.5提供了多个参数规模的版本0.8B版本适合移动设备和低配笔记本显存需求仅2GB4B版本平衡性能与资源消耗6GB显存即可流畅运行9B版本推荐配置8GB显存可获得接近GPT-4的体验35B及以上版本需要专业级显卡适合企业级应用对于大多数开发测试场景9B版本是最佳选择。我的测试环境搭载RTX 306012GB显存实测首token延迟800ms生成速度约15字/秒。2.2 软件工具链核心工具选择基于以下考量Ollama提供开箱即用的模型管理支持跨平台部署Spring Boot 3.x必须版本因Spring AI依赖Jakarta EE命名空间Spring AI 1.1.0专为Java生态设计的AI集成框架OpenJDK 17LTS版本保证长期支持提示避免使用JDK 8或11它们缺少Spring AI所需的新特性支持3. Ollama安装与配置3.1 跨平台安装指南Ollama的安装过程极其简单各平台具体步骤如下Windows系统访问 Ollama官网 下载安装包双击执行安装程序默认配置即可安装完成后系统托盘会出现羊驼图标右键选择Open Web UI验证安装Linux系统(Ubuntu)# 一键安装脚本 curl -fsSL https://ollama.com/install.sh | sh # 启动服务 sudo systemctl start ollama # 设置开机自启 sudo systemctl enable ollamamacOS系统# Homebrew安装 brew install ollama # 启动服务 brew services start ollama3.2 服务验证安装完成后执行以下命令验证ollama --version # 预期输出示例ollama version 0.6.0 ollama list # 应显示空列表尚未下载任何模型4. Qwen 3.5模型部署4.1 模型下载与选择Qwen 3.5提供多个版本根据硬件条件选择# 基础9B版本推荐 ollama pull qwen3.5:9b # 量化版本显存不足时使用 ollama pull qwen3.5:9b-q4_K_M # 超大杯版本需要24G显存 ollama pull qwen3.5:35b下载进度可通过以下命令查看ollama show --download4.2 本地测试验证模型下载完成后建议先通过命令行测试ollama run qwen3.5:9b进入交互模式后输入测试问题请用Java实现快速排序并分析时间复杂度正常应返回格式良好的代码和解释。按CtrlD退出交互模式。5. Spring Boot项目集成5.1 项目初始化使用Spring Initializr创建项目时需注意Java版本选择17或21必须包含Spring Web和Spring AI依赖打包方式建议选择JarMaven关键依赖配置dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.1.0-M3/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-ollama-spring-boot-starter/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency /dependencies5.2 关键配置详解application.yml配置示例spring: ai: ollama: base-url: http://localhost:11434 chat: model: qwen3.5:9b options: temperature: 0.7 # 控制生成随机性(0-1) num-predict: 1024 # 最大输出长度 num-ctx: 4096 # 上下文窗口大小 chat: client: enabled: true server: servlet: encoding: charset: UTF-8 enabled: true force: true参数说明temperature值越高输出越有创意越低则越保守num-predict限制生成内容长度防止过度消耗资源num-ctx影响模型记忆能力值越大显存占用越高6. 核心代码实现6.1 基础对话实现最简单的Controller实现RestController RequestMapping(/api/ai) public class AIController { private final ChatClient chatClient; public AIController(ChatClient.Builder builder) { this.chatClient builder.build(); } GetMapping(/ask) public String ask(RequestParam String question) { return chatClient.prompt() .user(question) .call() .content(); } }测试请求GET /api/ai/ask?question用Java实现二分查找6.2 进阶对话管理实现多轮对话需要维护会话状态Service public class ChatService { private final ChatClient chatClient; private final MapString, ListMessage sessionStore new ConcurrentHashMap(); public String chat(String sessionId, String userInput) { ListMessage history sessionStore.computeIfAbsent( sessionId, k - new ArrayList()); history.add(new UserMessage(userInput)); String response chatClient.prompt() .messages(history) .call() .content(); history.add(new AssistantMessage(response)); // 限制历史记录长度 if(history.size() 20) { history history.subList(history.size()-10, history.size()); sessionStore.put(sessionId, history); } return response; } }对应的REST端点PostMapping(/conversation) public String conversation(RequestBody ChatRequest request) { return chatService.chat(request.getSessionId(), request.getMessage()); } Data class ChatRequest { private String sessionId; private String message; }7. 性能优化技巧7.1 流式输出实现改善用户体验的关键技术GetMapping(value /stream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString streamChat(RequestParam String message) { return chatClient.prompt() .user(message) .stream() .content(); }前端配合示例(JavaScript):const eventSource new EventSource(/api/ai/stream?message你好); eventSource.onmessage (e) { document.getElementById(output).innerHTML e.data; };7.2 显存优化策略当资源受限时可采用以下方案使用量化模型ollama pull qwen3.5:9b-q4_K_M调整JVM参数java -Xmx4g -Xms4g -jar your-app.jar限制并发请求Configuration class AiConfig { Bean public Executor aiExecutor() { return Executors.newFixedThreadPool(2); // 根据GPU能力调整 } }8. 生产环境注意事项8.1 安全加固措施访问控制# 限制Ollama访问IP export OLLAMA_HOST0.0.0.0:11434 export OLLAMA_ORIGINShttp://your-domain.comAPI鉴权PostMapping(/secure/ask) public ResponseEntityString secureAsk( RequestHeader(X-API-KEY) String apiKey, RequestBody QuestionRequest request) { if(!your-secret-key.equals(apiKey)) { return ResponseEntity.status(403).build(); } // 处理请求... }8.2 监控与运维推荐监控指标显存使用率nvidia-smi请求响应时间并发请求数Token生成速度Prometheus配置示例metrics: ollama: enabled: true endpoint: http://localhost:11434/metrics9. 典型问题排查9.1 中文乱码问题解决方案确保application.yml配置了UTF-8检查系统locale设置locale -a | grep UTF-8添加JVM参数-Dfile.encodingUTF-89.2 模型加载失败排查步骤验证模型是否下载完成ollama list检查Ollama服务日志journalctl -u ollama -f尝试重新拉取模型ollama rm qwen3.5:9b ollama pull qwen3.5:9b9.3 内存泄漏处理预防措施使用try-with-resources管理资源限制上下文历史长度定期重启服务可通过K8s livenessProbe实现10. 扩展应用场景10.1 代码生成助手增强版实现PostMapping(/generate-code) public String generateCode(RequestBody CodeRequest request) { String prompt String.format( 请用%s语言实现以下功能 需求%s 要求 1. 包含完整的类结构 2. 添加必要的注释 3. 编写单元测试示例 , request.getLanguage(), request.getRequirement()); return chatClient.prompt() .user(prompt) .options(OllamaOptions.builder() .withTemperature(0.3) // 降低随机性保证代码质量 .build()) .call() .content(); }10.2 文档自动生成结合Swagger的实现PostMapping(/generate-docs) public String generateApiDocs(RequestBody OpenApiSpec spec) { String prompt String.format( 根据以下OpenAPI规范生成Markdown格式文档 %s 要求 1. 包含所有端点说明 2. 给出示例请求/响应 3. 使用中文描述 , spec.toString()); return chatClient.prompt() .user(prompt) .call() .content(); }经过实际项目验证这套JavaOllama的方案在响应速度、资源消耗和开发效率上达到了很好的平衡。特别是在企业内网环境中数据不出域的特性解决了敏感数据处理的合规性问题。