Aspire 集成 Qdrant 向量数据库:Aspire.Hosting.Qdrant 实战指南
【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire
Aspire 的 Qdrant 托管集成(Hosting Integration)允许你在 Aspire 应用模型中以代码优先的方式建模、配置并编排一个 Qdrant 向量数据库容器资源,并通过WithReference将连接信息注入到任意消费方(.NET 项目、Node.js 应用、其他容器)。本文基于src/Aspire.Hosting.Qdrant模块的源码与文档,完整讲解从安装、声明资源、连接属性到客户端消费、数据持久化与部署清单的端到端用法。
集成概览:它在 Aspire 解决方案中扮演什么角色
Qdrant 是一个面向 AI/机器学习场景的向量数据库,常被用于语义检索、RAG(检索增强生成)等应用。在 Aspire 中,Aspire.Hosting.Qdrant集成的作用是:
- 模型化:将 Qdrant 服务器抽象为一个
QdrantServerResource资源对象,纳入 Aspire 的应用模型; - 配置:自动处理容器镜像、gRPC/HTTP 双端点、API Key 参数、健康检查等基础设施细节;
- 编排:在本地开发时以 Docker 容器方式启动 Qdrant,在发布时生成可部署的 manifest。
该集成由两部分协同工作:位于 src/Aspire.Hosting.Qdrant 的托管集成(AppHost 侧,负责编排服务器),以及 src/Components/Aspire.Qdrant.Client 的客户端组件(业务服务侧,负责注入QdrantClient供 DI 消费)。
快速开始:将集成添加到 AppHost
从 AppHost 项目目录执行以下 Aspire CLI 命令,即可将Aspire.Hosting.Qdrant集成加入当前解决方案:
aspire add Aspire.Hosting.Qdrant该命令会完成包引用与必要的项目配置。也可以手动通过dotnet add package Aspire.Hosting.Qdrant在 AppHost 项目中添加包引用(参见 src/Components/Aspire.Qdrant.Client/README.md 中的 AppHost extensions 一节)。
声明 Qdrant 资源并建立引用
C#(.NET AppHost)
在 AppHost 的Program.cs中调用AddQdrant声明资源,再通过WithReference让其他资源引用它:
var qdrant = builder.AddQdrant("qdrant"); var myService = builder.AddProject<Projects.MyService>() .WithReference(qdrant);TypeScript(Polyglot AppHost)
在 TypeScript 版 AppHost 中用法等价,使用小驼峰的addQdrant与withReference:
const qdrant = await builder.addQdrant("qdrant"); const myService = await builder.addNodeApp("myService", "../my-service", "server.js") .withReference(qdrant);业务服务侧消费连接
在被引用的MyService项目中,安装Aspire.Qdrant.Client后调用AddQdrantClient注册QdrantClient:
builder.AddQdrantClient("qdrant");之后即可通过依赖注入获取QdrantClient执行向量集合、点(point)的增删改查等操作。
AddQdrant 方法签名与底层实现细节
AddQdrant定义在 src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs,其完整签名如下:
public static IResourceBuilder<QdrantServerResource> AddQdrant( this IDistributedApplicationBuilder builder, string name, IResourceBuilder<ParameterResource>? apiKey = null, int? grpcPort = null, int? httpPort = null)各参数说明:
| 参数 | 类型 | 含义 |
|---|---|---|
name | string | 资源名称,同时用作被引用方连接字符串的名称 |
apiKey | IResourceBuilder<ParameterResource>? | 用于提供 Qdrant API Key 的参数;传null时自动生成名为{name}-Key的随机密码参数 |
grpcPort | int? | gRPC 端点在宿主机上的端口(容器内固定为 6334) |
httpPort | int? | HTTP 端点在宿主机上的端口(容器内固定为 6333) |
源码中硬编码的两个容器端口常量(QdrantBuilderExtensions.cs)为:
QdrantPortGrpc = 6334:Qdrant gRPC 接口(.NET 客户端默认走此通道);QdrantPortHttp = 6333:Qdrant REST/HTTP 接口。
默认使用的容器镜像定义在 src/Aspire.Hosting.Qdrant/QdrantContainerImageTags.cs:
- Registry:
docker.io - Image:
qdrant/qdrant - Tag:
v1.18.0(当前仓库锁定版本)
端点与传输协议
AddQdrant内部通过WithHttpEndpoint暴露两个命名端点,资源类QdrantServerResource中定义了端点常量(QdrantServerResource.cs):
| 端点名 | 用途 | 容器端口 | 传输协议 |
|---|---|---|---|
grpc(主端点) | gRPC 数据通道 | 6334 | http2 |
http | REST/HTTP 接口及 Web UI | 6333 | http |
gRPC 端点被显式标记为http2传输;同时集成会为 HTTP 端点注册两个便于访问的仪表盘入口:Qdrant (GRPC)显示在详情页,Qdrant (HTTP)与Qdrant Dashboard(指向/dashboard)作为资源链接显示。
API Key 的自动生成与环境注入
当不显式传入apiKey参数时,AddQdrant会调用CreateDefaultPasswordParameter自动生成{name}-Key随机密码参数。随后该密钥通过环境变量QDRANT__SERVICE__API_KEY注入容器(QdrantBuilderExtensions.cs):
context.EnvironmentVariables[ApiKeyEnvVarName] = qdrant.ApiKeyParameter; // QDRANT__SERVICE__API_KEY在发布模式(IsPublishMode)下,还会额外注入QDRANT__SERVICE__ENABLE_STATIC_CONTENT=0以关闭 Qdrant 内置的 Dashboard Web UI,避免在生产部署中暴露不必要的静态内容。
连接属性详解(Connection Properties)
当消费方通过WithReference引用 Qdrant 资源时,以下连接属性会暴露给消费项目(表格来自 src/Aspire.Hosting.Qdrant/README.md,底层实现在 QdrantServerResource.cs 的GetConnectionProperties):
| 属性名 | 说明 |
|---|---|
GrpcHost | Qdrant 服务器的 gRPC 主机名 |
GrpcPort | Qdrant 服务器的 gRPC 端口 |
HttpHost | Qdrant 服务器的 HTTP 主机名 |
HttpPort | Qdrant 服务器的 HTTP 端口 |
ApiKey | 用于认证的 API Key |
Uri | gRPC 连接 URI,格式为http://{GrpcHost}:{GrpcPort} |
HttpUri | HTTP 连接 URI,格式为http://{HttpHost}:{HttpPort} |
环境变量命名规则
Aspire 将上述每个属性以[RESOURCE]_[PROPERTY]的命名规则暴露为环境变量。例如名为db1的资源的Uri属性会变成环境变量DB1_URI;HttpUri则对应DB1_HTTPURI。这组连接属性测试的期望值可参见 tests/Aspire.Hosting.Qdrant.Tests/ConnectionPropertiesTests.cs,其中验证了每个属性的表达式形态,如Uri对应{qdrant.bindings.grpc.url}。
WithReference 注入的连接字符串
除了按属性展开的环境变量外,WithReference(QdrantBuilderExtensions.cs)还会向消费方注入两套连接字符串:
ConnectionStrings__{connectionName}:gRPC 连接字符串,形如Endpoint=http://localhost:6334;Key=...;ConnectionStrings__{connectionName}_http:HTTP 连接字符串,形如Endpoint=http://localhost:6333;Key=...。
连接字符串格式由 QdrantServerResource.cs 定义,为Endpoint={uri};Key={apiKey}。测试 tests/Aspire.Hosting.Qdrant.Tests/AddQdrantTests.cs 验证了容器内引用时端点会解析为my-qdrant.dev.internal内部网络地址,且项目与容器两类消费方均能获得正确注入。
客户端组件:Aspire.Qdrant.Client 的三种配置方式
Aspire.Qdrant.Client(源码见 src/Components/Aspire.Qdrant.Client)将QdrantClient注册为单例,并默认附带健康检查。注册入口为AddQdrantClient(connectionName, configureSettings?)与键控版本AddKeyedQdrantClient(name, configureSettings?)(AspireQdrantExtensions.cs)。
方式一:使用连接字符串
通过ConnectionStrings配置节提供连接字符串,键名与AddQdrantClient传入的名称一致:
{ "ConnectionStrings": { "qdrant": "Endpoint=http://localhost:6334;Key=123456!@#$%" } }builder.AddQdrantClient("qdrant");默认情况下QdrantClient使用 gRPC API 端点(即连接字符串中的Endpoint指向 6334 端口)。连接字符串的解析逻辑(ParseConnectionString)在 QdrantClientSettings.cs:既支持裸 URI(http://...),也支持Endpoint=...;Key=...键值对形式。
方式二:使用配置提供程序
组件从Aspire:Qdrant:Client配置节加载设置,也支持按连接名命名的子节(Aspire:Qdrant:Client:{connectionName}):
{ "Aspire": { "Qdrant": { "Client": { "Key": "123456!@#$%" } } } }方式三:使用内联委托
通过Action<QdrantClientSettings> configureSettings在代码中直接设置选项,例如:
builder.AddQdrantClient("qdrant", settings => settings.Key = "12345!@#$%");QdrantClientSettings支持的设置项(QdrantClientSettings.cs):
| 属性 | 默认值 | 说明 |
|---|---|---|
Endpoint | null | Qdrant 服务器端点 URI |
Key | null | 连接所需的 API Key |
DisableHealthChecks | false | 是否禁用客户端健康检查 |
HealthCheckTimeout | null | 健康检查超时时间 |
数据持久化:数据卷与绑定挂载
Qdrant 的数据存储在容器内的/qdrant/storage目录。集成提供两个持久化扩展方法(QdrantBuilderExtensions.cs):
WithDataVolume(name?, isReadOnly?)—— 命名卷,名称缺省时自动生成(基于资源名):
var qdrant = builder.AddQdrant("qdrant") .WithDataVolume(); // 可选:.WithDataVolume("qdrant-data", isReadOnly: false)WithDataBindMount(source, isReadOnly?)—— 绑定挂载,将宿主机目录映射进容器:
var qdrant = builder.AddQdrant("qdrant") .WithDataBindMount("/data/qdrant", isReadOnly: false);两者都挂载到容器内的/qdrant/storage,保证容器重建后向量数据不丢失。
健康检查与可观测性
集成在服务器侧与客户端侧各注册了一个健康检查:
- 服务器侧:
AddQdrant订阅ConnectionStringAvailableEvent,在连接字符串就绪后创建QdrantClient,并注册名为{name}_check的健康检查(QdrantBuilderExtensions.cs); - 客户端侧:
AddQdrantClient默认注册Qdrant.Client(键控场景为Qdrant.Client_{connectionName})健康检查,实现类 QdrantHealthCheck.cs 通过调用QdrantClient.HealthAsync验证服务器返回的Title字段来判断健康状态,失败或异常时报告Unhealthy。
这些健康检查会参与 Aspire 的资源状态展示与依赖就绪判断,是本地开发与部署时资源"可观测"能力的一部分。
部署与 Manifest
在发布(Publish)模式下,AddQdrant生成的资源会产出container.v0类型的 manifest。测试 tests/Aspire.Hosting.Qdrant.Tests/AddQdrantTests.cs 给出了两种典型形态:
自动生成 API Key 时:
{ "type": "container.v0", "connectionString": "Endpoint={qdrant.bindings.grpc.url};Key={qdrant-Key.value}", "image": "docker.io/qdrant/qdrant:v1.18.0", "env": { "QDRANT__SERVICE__API_KEY": "{qdrant-Key.value}", "QDRANT__SERVICE__ENABLE_STATIC_CONTENT": "0" }, "bindings": { "grpc": { "scheme": "http", "protocol": "tcp", "transport": "http2", "targetPort": 6334 }, "http": { "scheme": "http", "protocol": "tcp", "transport": "http", "targetPort": 6333 } } }显式传入QdrantApiKey参数时,连接字符串与环境变量中的密钥引用变为{QdrantApiKey.value},密钥由外部参数源在部署时提供,避免硬编码。这也印证了发布模式下QDRANT__SERVICE__ENABLE_STATIC_CONTENT会被置为0以关闭 Dashboard。
指定宿主机端口
需要固定宿主机端口时,通过AddQdrant的grpcPort与httpPort参数指定(容器内目标端口仍为 6334/6333):
var qdrant = builder.AddQdrant("my-qdrant", grpcPort: 5503, httpPort: 5504);该行为由测试 AddQdrantTests.cs 验证:宿主机端口变为 5503/5504,而TargetPort保持 6334/6333 不变,两个端点均为非外部(IsExternal = false)TCP 端点。
深入阅读指引
- 托管集成源码:src/Aspire.Hosting.Qdrant/QdrantBuilderExtensions.cs、src/Aspire.Hosting.Qdrant/QdrantServerResource.cs、src/Aspire.Hosting.Qdrant/QdrantContainerImageTags.cs
- 客户端组件源码:src/Components/Aspire.Qdrant.Client/AspireQdrantExtensions.cs、src/Components/Aspire.Qdrant.Client/QdrantClientSettings.cs、src/Components/Aspire.Qdrant.Client/QdrantHealthCheck.cs
- 测试用例:tests/Aspire.Hosting.Qdrant.Tests/AddQdrantTests.cs、tests/Aspire.Hosting.Qdrant.Tests/ConnectionPropertiesTests.cs
- 客户端组件 README:src/Components/Aspire.Qdrant.Client/README.md
注:Qdrant 及 Qdrant 标志为德国 Qdrant Solutions GmbH 的商标或注册商标,经许可使用。
【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考