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

Spring AI Ollama 连接超时问题排查与解决:OkHttp 读超时配置全指南

Spring AI Ollama 连接本地模型超时问题完全解决指南

一、问题现象

在 Spring Boot 3.2.5 项目中使用spring-ai-ollama-spring-boot-starter(版本 1.0.0-M6)连接本地 Ollama 部署的qwen2.5:7b-instruct模型时,调用聊天接口(例如 RAG 问答)会在约 10 秒后抛出以下异常:

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://localhost:11434/api/chat": timeout at org.springframework.web.client.DefaultRestClient... Caused by: java.net.SocketTimeoutException: timeout at okio.SocketAsyncTimeout.newTimeoutException(JvmOkio.kt:146) at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(...)

尽管在application.yml中已经配置了spring.ai.ollama.chat.options.timeout: 120s,超时仍然准时在 10 秒左右发生,导致模型生成未完成就被中断。

二、问题场景

  • 本地 Ollama 模型响应慢:使用 7B 或更大参数量的模型(如qwen2.5:7b-instruct),或者提问复杂度较高时,Ollama 服务端需要较长时间(可能十几秒甚至几十秒)才能返回第一个 token 或完整响应。
  • 只配置了服务端超时,未配置客户端 HTTP 超时:开发者往往认为spring.ai.ollama.chat.options.timeout就足够控制整个请求的超时,但实际它只控制发送给 Ollama API 的timeout参数(告诉服务端最多生成多久),并不影响 Java 客户端等待响应的时长。
  • 底层 HTTP 客户端为 OkHttp:Spring AI Ollama 在无自定义配置时,默认通过OkHttp3ClientHttpRequestFactory使用 OkHttp 发起请求。OkHttp 的默认读超时为10 秒,这就是超时发生在 10 秒的根本原因。

三、根因分析

1. 两层超时机制相互独立

  • 模型层超时(chat.options.timeout
    该值会被序列化到POST /api/chat请求体中的options.timeout字段,用于告知 Ollama 服务端允许的最长生成时间。服务端如果超时,会主动中断生成并返回错误。

  • HTTP 客户端层超时(OkHttp 读超时)
    这是 Java 应用等待服务器返回响应的最大时间。如果服务端处理慢(比如模型生成耗时较长),客户端会在达到读超时后直接抛出SocketTimeoutException无论服务端是否仍在正常工作
    OkHttp 默认readTimeout = 10_000ms(10 秒)。

只有 HTTP 读超时 > 模型生成所需时间时,请求才能正常完成。反之,即使服务端允许生成更久,客户端也会先断开连接。

2. 常见配置为何不生效?

  • spring.restclient.read-timeout无效
    spring.restclient属性通过RestClientCustomizer全局修改RestClient.Builder,但 Spring AI Ollama 自动配置内部是独立创建RestClient的,并未应用全局定制器,因此该配置无法传递到 Ollama 所用客户端。

  • SimpleClientHttpRequestFactory无效
    实际堆栈中显示底层为okhttp3.OkHttpClient,而非 JDK 默认的HttpURLConnection(对应SimpleClientHttpRequestFactory)。配置后者当然不起作用。

  • spring.okhttp.read-timeout无效(或直接启动报错)
    Spring Boot 对 OkHttp 的属性前缀是spring.okhttp,而非okhttp。即使写成正确前缀,Ollama 自动配置也可能没有使用 Spring 管理的OkHttpClientBean,而是直接创建了一个默认OkHttpClient,因此全局配置同样不生效。

此外,若在 YAML 中不慎写出两个顶级spring:键,会触发DuplicateKeyException导致启动失败。

4. 自定义 Bean 时的常见坑

直接创建OllamaApiBean 时,需注意其构造函数签名在 1.0.0-M6 版本中为:

publicOllamaApi(StringbaseUrl,RestClient.BuilderrestClientBuilder,WebClient.BuilderwebClientBuilder)

而不是(String, RestClient)。错误地调用构造函数会导致编译失败。


四、最终解决方案

自定义OllamaApiBean,显式控制 OkHttp 超时

直接通过配置类覆盖OllamaApiBean,创建一个具有足够长读超时的OkHttpClient,并将其通过RestClient.Builder注入到OllamaApi中。此方案完全绕过 Spring 的全局 OkHttp 配置,从根源上解决问题。

步骤:

  1. 在项目中新增配置类OllamaTimeoutConfig.java
  2. 使用@Value注入spring.ai.ollama.base-url
  3. 构建自定义超时的OkHttpClient
  4. 创建RestClient.Builder并设置OkHttp3ClientHttpRequestFactory(虽然已过时,但功能正常,可忽略警告)。
  5. 提供空WebClient.Builder实例。
  6. 调用正确的OllamaApi三参数构造器并返回 Bean。

完整代码:

packagecom.badao.ai.config;importokhttp3.OkHttpClient;importorg.springframework.ai.ollama.api.OllamaApi;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.http.client.OkHttp3ClientHttpRequestFactory;importorg.springframework.web.client.RestClient;importorg.springframework.web.reactive.function.client.WebClient;importjava.time.Duration;@ConfigurationpublicclassOllamaTimeoutConfig{@Value("${spring.ai.ollama.base-url}")privateStringbaseUrl;@BeanpublicOllamaApiollamaApi(){// 1. 自定义 OkHttpClient 超时OkHttpClientokHttpClient=newOkHttpClient.Builder().connectTimeout(Duration.ofSeconds(30))// 连接超时.readTimeout(Duration.ofMinutes(3))// 读超时 3 分钟,大于模型 timeout.writeTimeout(Duration.ofSeconds(60))// 写超时.build();// 2. 创建 OkHttp3ClientHttpRequestFactory(已过时但可用)OkHttp3ClientHttpRequestFactoryfactory=newOkHttp3ClientHttpRequestFactory(okHttpClient);// 3. 构建 RestClient.Builder,注入自定义 factoryRestClient.BuilderrestClientBuilder=RestClient.builder().baseUrl(baseUrl).requestFactory(factory);// 4. 提供 WebClient.Builder(必须,传默认空 builder 即可)WebClient.BuilderwebClientBuilder=WebClient.builder();// 5. 调用 OllamaApi 实际构造函数returnnewOllamaApi(baseUrl,restClientBuilder,webClientBuilder);}}

YAML 配置精简:
既然已经通过代码完全掌控了 HTTP 客户端超时,就可以移除application.yml中的spring.restclientspring.okhttp等无关超时配置,保持清晰:

server:port:885logging:level:com.badao:debugorg.springframework.ai:debugspring:ai:ollama:base-url:http://localhost:11434chat:options:model:qwen2.5:7b-instructtemperature:0.5timeout:120s# 服务端模型生成超时,依然建议保留embedding:options:model:nomic-embed-texttimeout:120sservlet:multipart:max-file-size:10MBmax-request-size:10MB

关键要点

  • 读超时必须大于模型超时:这里readTimeout = 3 分钟,而chat.options.timeout = 2 分钟,留有充足缓冲。
  • OkHttp3ClientHttpRequestFactory过时警告:不影响功能,可忽略。如需消除,需整体切换到其他 HTTP 客户端(如 JDK HttpClient),但会增加配置复杂度,不值得。
  • 不要添加额外的 YAML OkHttp 配置,避免干扰。

五、验证效果

  1. 重新编译并启动应用。
  2. 发送之前会导致超时的 RAG 请求。
  3. 观察日志,不再出现Read timed outSocketTimeoutException
  4. 模型正常返回生成结果,即使耗时超过 10 秒、甚至 1 分钟,也能顺利完成。

六、总结

本次问题的本质是Spring AI Ollama 使用的底层 OkHttp 读超时默认过短,且 YAML 配置中的服务端超时选项无法控制客户端行为,加上 Spring Boot 全局 OkHttp 属性与 Ollama 自动配置并不互通,导致常规配置尝试全部失效。
最终通过自定义OllamaApiBean 直接构建带超时的OkHttpClient,并依其正确的构造函数注入,彻底解决了超时问题。该方案稳定可靠,推荐遇到同类问题的开发者采用。

http://www.jsqmd.com/news/951282/

相关文章:

  • 告别pip install失败!手把手教你两种搞定Python Click安装的方法(含离线包下载)
  • 安卓个人记账App完整可运行工程:含APK安装包、MySQL后端对接源码与AS开发环境
  • 3步轻松解决博德之门3模组混乱问题:BG3ModManager完全指南
  • 2026 保山卫生间漏水、外墙、楼顶、地下室、阳光房渗漏维修师傅推荐|同城附近上门防水补漏公司测评 - 企业资讯
  • 实战应用:基于快马生成的代码打造个人专属tvbox配置管理工具
  • 告别重复劳动:用快马AI智能生成ROS消息、服务与启动文件
  • 基于Arduino Pro Mini的便携式游戏机DIY全流程指南
  • 2026年炸鸡店创业品牌推荐榜:合肥/南京韩式炸鸡外卖,低成本社区档口与夜宵店优质之选! - 品牌企业推荐师(官方)
  • 保姆级教程:用D435i录制ROS bag文件,一步步转成BundleFusion能吃的.sens格式
  • 2026昆山PLC培训排行:从硬件到就业的客观评估 - 互联网科技品牌测评
  • 电缆钢丝绳缺陷损伤智能检测系统|YOLOv8电力桥梁基础设施安全监测解决方案
  • 如何高效进行单倍体变异检测:Snippy工具实战指南
  • C++11(二) 革新:引用折叠与lambda表达式
  • 告别熬夜改PPT!百考通AI,一站式解决高校答辩PPT制作难题
  • LinkSwift:5分钟掌握网盘直链解析终极方案,告别限速烦恼
  • 3步免费解锁Grammarly Premium高级版:autosearch-grammarly-premium-cookie完整指南
  • 从振动信号到故障预警:手把手教你用Python实现时域特征提取(以峭度、裕度因子为例)
  • 2026 潮州卫生间漏水、外墙、楼顶、地下室、阳光房渗漏维修师傅推荐|同城附近上门防水补漏公司测评 - 企业资讯
  • 2026 成都卫生间漏水、外墙、楼顶、地下室、阳光房渗漏维修师傅推荐|同城附近上门防水补漏公司测评 - 企业资讯
  • 政企专属的私有化安全协作平台,构建金融级全链路安全防护体系
  • 【元器件专题】MOS管上下桥设计详解(死区时间)
  • 6.2【A】
  • 如何在微信小程序中快速生成二维码:weapp-qrcode终极指南
  • 当技能遇见AI:利用快马平台智能生成具备自然语言解析的待办事项技能
  • 手把手教你学Simulink——基于状态空间平均法(SSA)的 DC‑DC 变换器小信号模型仿真
  • 网络投票平台推荐,深度测评2026年6月已更新 - 投票小程序
  • 计算机毕业设计之基于数据挖掘算法的电影推荐系统
  • 央视大推特推的OPC(一人公司),我做了!
  • 保姆级教程:用ENVI 5搞定高光谱VNIR与SWIR影像的融合拼接(附公共ROI裁剪技巧)
  • 2026 泸州卫生间漏水、外墙、楼顶、地下室、阳光房渗漏维修师傅推荐|同城附近上门防水补漏公司测评 - 企业资讯