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

【码动四季】夏|SpringBoot 集成 Qdrant 报 UNAVAILABLE: No servers found 完整踩坑修复方案

SpringBoot集成Qdrant报UNAVAILABLE: No servers found 完整踩坑修复方案

一、问题现象

本地单元测试单独调用Qdrant客户端完全正常,SpringBoot项目启动后,业务代码调用Qdrant向量库接口直接抛出gRPC异常:

io.grpc.StatusRuntimeException:UNAVAILABLE:Noservers foundfor127.0.0.1:6334

网络层面验证:
Qdrant 服务正常监听0.0.0.0:6333/6334端口;
Windows 命令行Test-NetConnection 127.0.0.1 -Port 6334返回 TCP 连接成功;
无 xds、服务发现、round_robin 负载均衡相关自定义配置。

二、问题根因

1.双 Netty 传输依赖冲突
项目同时存在两套 gRPC Netty 实现:

  • SpringBoot gRPC 组件传递引入 io.grpc:grpc-netty(原生 netty);
  • Qdrant 客户端依赖 io.grpc:grpc-netty-shaded:1.51.0(隔离版 netty)。

二者 SPI 优先级相同,打包后优先加载原生 netty,且 Qdrant 依赖排除原生 netty 类,导致通道创建成功但无法建立连接。
单元测试无 SpringBoot gRPC 依赖,仅存在 shaded 包,因此测试正常。

2. Windows 下 gRPC DNS 解析器兼容问题
即便强制使用 shaded 通道,Windows 环境默认DnsNameResolver解析纯 IP 地址不稳定,会返回空地址列表,gRPC 判定无可用服务节点,抛出No servers found。

三、最终修复方案:自定义静态 NameResolver

核心思路:抛弃默认 DNS 解析逻辑,预解析 IP 生成固定地址列表,绕过不稳定解析器;同时显式使用 shaded Netty 构建通道,隔离两套 netty 实现。

importio.grpc.*;importio.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importio.qdrant.client.QdrantClient;importjava.net.InetAddress;importjava.net.InetSocketAddress;importjava.net.UnknownHostException;importjava.util.Collections;importjava.util.List;@ConfigurationpublicclassQdrantConfig{@Value("${qdrant.host:127.0.0.1}")privateStringhost;@Value("${qdrant.port:6334}")privateintport;@BeanpublicQdrantClientqdrantClient()throwsUnknownHostException{// 预解析IP地址InetAddressaddress=InetAddress.getAllByName(host)[0];List<EquivalentAddressGroup>addressGroups=Collections.singletonList(newEquivalentAddressGroup(newInetSocketAddress(address,port)));// 自定义静态地址解析工厂NameResolver.FactoryfixedNameResolverFactory=newNameResolver.Factory(){@OverridepublicNameResolvernewNameResolver(URItargetUri,NameResolver.Argsargs){returnnewNameResolver(){@OverridepublicStringgetServiceAuthority(){returnhost+":"+port;}@Overridepublicvoidstart(Listener2listener){System.out.println("Qdrant静态解析地址列表:"+addressGroups);listener.onAddresses(addressGroups,Attributes.EMPTY);}@Overridepublicvoidshutdown(){}};}@OverridepublicStringgetDefaultScheme(){return"fixed";}};// 使用shaded netty构建通道,绑定自定义解析器与pick_first负载均衡ManagedChannelchannel=NettyChannelBuilder.forTarget("fixed://"+host+":"+port).nameResolverFactory(fixedNameResolverFactory).defaultLoadBalancingPolicy("pick_first").usePlaintext().keepAliveTime(10,TimeUnit.SECONDS).build();returnnewQdrantClient(channel);}}

2. Service 层规范改造

采用 lombok 构造注入,清理冗余注解与无用导入:

importlombok.RequiredArgsConstructor;importio.qdrant.client.QdrantClient;importorg.springframework.stereotype.Service;@Service@RequiredArgsConstructorpublicclassQdrantServiceImpl{privatefinalQdrantClientqdrantClient;// 向量集合创建、检索、写入等业务方法}

四、验证效果

项目启动日志输出静态地址:Qdrant静态解析地址列表:[/127.0.0.1:6334];
调用 Qdrant 所有接口不再抛出No servers found异常;
单元测试、SpringBoot 运行环境完全兼容;
项目内其他 gRPC 服务不受改动影响,传输层完全解耦。

五、方案取舍说明

不推荐全局排除原生 grpc-netty
直接排除grpc-netty虽能统一 shaded 包,但 SpringBoot gRPC 服务端构建器强依赖原生 netty,排除后会导致内部 gRPC 服务启动失败,改动范围大、风险高。本方案仅针对 Qdrant 客户端单独隔离,最小侵入业务。

长期统一 netty 优化方案
若后续项目全量使用 shaded netty,可在父工程依赖管理统一管控 gRPC 版本,通过配置grpc.netty.server.mode=shaded切换全局传输实现,可作为后续独立优化项。

六、开发踩坑总结

No servers found核心根源优先定位NameResolver地址解析结果,而非 Netty 线程池;
Windows 本地开发,gRPC 默认 DNS 解析器对纯 IP 存在兼容性缺陷;
Classpath 同时存在两套 gRPC Netty 依赖时,典型特征为单测正常、运行报错;
TCP 连通不代表 gRPC 服务可用,gRPC 拥有独立地址解析、负载均衡链路;
网络通用 Netty 冲突方案不一定适配向量库客户端,请勿直接复制通用代码。

七、application.yml 配置

qdrant:host:127.0.0.1port:6334
http://www.jsqmd.com/news/1214187/

相关文章:

  • 近期量化工具试用方法,先定功能再跑最小闭环
  • MyBot安全使用指南:避免账号风险与游戏规则冲突的终极教程
  • 文本到视频的4K时代:Veo 3.1和LTX-2.3如何实现原生4K视频生成
  • 微米级位移传感器:毫米行程下的纳米级测量精度
  • Header Editor完全指南:5分钟学会浏览器请求控制的终极技巧
  • 2026西安雁塔区二手奢侈品回收怎么选?易奢福连锁品牌综合实力全面测评 - 易奢福
  • 吕匠家电维修智能家电适配强,晋城开发区家电维修优选 - 百航
  • 仅限本周开放!360AI搜索高级语法速查卡(含18个未文档化参数及响应码含义)
  • 如何实现微信聊天记录永久保存?这款开源工具让你真正拥有自己的数字记忆
  • TacentView图像查看器完整指南:游戏开发者的纹理查看终极工具
  • 近期量化软件选型,能力基础决定工具负担
  • 最新小策略量化练习,从流程感判断工具增量
  • 奔赴少年CIIU携首张迷你专辑高调回归 开启C-Tro Pop音乐新篇章
  • 上海徐汇首饰回收|2026 行业避坑标准与真实成交实测 - 全国二奢机构参考
  • 企业AI自动化落地失败率高达68%(2025Q3实测数据):2026生存指南——从PoC到ROI的9步闭环
  • 2026武汉二手名表市场走势深度解析:现阶段闲置腕表出手是否具备高性价比 - 企业家观察员
  • Spring知识梳理(5)
  • REFramework终极指南:一键解锁RE引擎游戏无限可能
  • Llama模型离线部署全链路拆解(含Mac/Win/Linux三端适配+量化压缩实战)
  • 【读书笔记】《命悬一线,我不放手:ICU的生死录》
  • 2026安徽成人本科院校排行榜——推荐安徽大学,双一流,211,安徽省重点大学! - 小张zc
  • cann/asc-devkit SIMT API半精度转换函数
  • 2026年滨湖区健康管理新趋势:细胞科技融入健康服务闭环
  • 智慧教育平台电子课本下载器终极指南:三步快速获取教学资源PDF
  • DLSS Swapper终极指南:三步搞定游戏性能优化,免费提升帧率45%
  • Dante Cloud蓝绿部署:零downtime的服务更新方案
  • 安珂瑞:一颗“智能炸弹“的抗癌二十年,一颗专门找癌细胞的“智能病毒“
  • 广州上门回收爱彼/沛纳海/积家,高端运动奢华腕表专业估价 - 商业每日快报
  • 【高考蓝皮书】2026高考数学试题分析(完整电子版pdf)
  • 2026创业项目-直播间团播动态16级灯牌横幅框感谢大哥升级特效动画透明海报素材ae工程文件 - 胖头鱼美文