本文介绍如何通过在应用主机项目中编写代码来进一步自定义资源的行为。 其中 .NET.NET Aspire, 资源 是云原生应用程序的依赖部分。 资源类型包括:
- .NET 项目:一个自定义微服务,负责云原生应用程序中的特定功能,通常由单独的开发人员团队生成。
- 可执行文件:如果需要使用工具构建微服务,例如 Node.js 或 Orleans,它们会作为可执行资源运行。
- 容器:可以基于特定映像添加Docker容器到您的.NET Aspire解决方案。
- 集成资源:集成通常向应用程序添加数据库、缓存和消息传送服务等资源。
有关业务流程的 .NET.NET Aspire 基础知识及其管理资源的方式,请参阅 .NET.NET Aspire 业务流程概述。
资源命名约定
资源 .NET Aspire 必须遵循资源 .NET Aspire 所代表的命名限制以及资源所代表的技术。 例如, .NET Aspire 资源的最大名称长度为 64 个字符,但 Azure 容器应用的最大长度为 32。 发布 .NET Aspire 容器资源 Azure时,名称长度不得超过 32 个字符。
.NET .NET Aspire 资源名称必须遵循以下基本规则:
- 长度必须为 1 到 64 个字符。
- 必须 以 ASCII 字母开头。
- 必须 仅包含 ASCII 字母、数字和连字符。
- 不能 以连字符结尾。
- 不得 包含连续连字符。
设置显式资源启动
默认情况下,项目、可执行文件和容器资源会自动启动分布式应用程序。 可以将资源配置为使用 WithExplicitStart 方法等待显式启动指令。 使用 WithExplicitStart 配置的资源使用 KnownResourceStates.NotStarted进行初始化。
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
builder.AddProject<Projects.AspireApp_DbMigration>("dbmigration")
.WithReference(postgresdb)
.WithExplicitStart();
在前面的代码中,资源 "dbmigration"
配置为不自动启动分布式应用程序。
可以通过单击“开始”命令从 .NET.NET Aspire 仪表板启动具有显式启动的资源。 有关详细信息,请参阅 .NET.NET Aspire 仪表板:停止或启动资源。
正在等待资源
在某些情况下,可能需要等待资源准备就绪,然后再启动另一个资源。 例如,可能需要等待数据库准备就绪,然后再启动依赖于它的 API。 若要表达此依赖项,请使用 WaitFor 方法:
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(postgresdb)
.WaitFor(postgresdb);
在前面的代码中,“apiservice”项目资源等待“postgresdb”数据库资源进入 KnownResourceStates.Running 状态。 示例代码显示了 .NET AspirePostgreSQL 集成,但相同的模式可以应用于其他资源。
其他情况可能需要等待某个资源在 KnownResourceStates.Exited 或 KnownResourceStates.Finished 完成运行后,再启动从属资源。 若要等待资源运行完成,请使用 WaitForCompletion 方法:
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder.AddPostgres("postgres");
var postgresdb = postgres.AddDatabase("postgresdb");
var migration = builder.AddProject<Projects.AspireApp_Migration>("migration")
.WithReference(postgresdb)
.WaitFor(postgresdb);
builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(postgresdb)
.WaitForCompletion(migration);
在前面的代码中,“apiservice”项目资源会等待“迁移”项目资源运行完成之后才开始。 “迁移”项目资源等待“postgresdb”数据库资源进入 KnownResourceStates.Running 状态。 例如,在启动 API 服务之前,在想要运行数据库迁移的情况下,这非常有用。
强制启动仪表板中的资源
可以使用仪表板中的 “开始” 命令绕过等待资源。 在仪表板中选择等待资源上的开始指示它立即开始,无需等待资源健康或完成。 如果想要立即测试资源,并且不想等待应用处于正确状态,这非常有用。
用于添加和表达资源的 API
.NET .NET Aspire 托管集成 和 客户端集成 都作为 NuGet 包提供,但它们的作用不同。 虽然 客户端集成 提供客户端库配置,以供在应用主机范围之外使用的应用程序使用,托管集成 则提供 API,以便在应用主机内表达资源和依赖项。 有关详细信息,请参阅 .NET.NET Aspire 集成概述:集成责任。
声明容器资源
若要表达 ContainerResource,请通过调用 IDistributedApplicationBuilder 方法将其添加到 AddContainer 实例:
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddContainer("ollama", "ollama/ollama")
.WithBindMount("ollama", "/root/.ollama")
.WithBindMount("./ollamaconfig", "/usr/config")
.WithHttpEndpoint(port: 11434, targetPort: 11434, name: "ollama")
.WithEntrypoint("/usr/config/entrypoint.sh")
.WithContainerRuntimeArgs("--gpus=all");
有关详细信息,请参阅
前面的代码通过镜像 ollama/ollama
添加了一个名为“ollama”的容器资源。 容器资源配置了多个绑定挂载、一个命名的 HTTP 端点、一个解析到 Unix shell 脚本的入口点,以及通过 WithContainerRuntimeArgs 方法指定的容器运行参数。
自定义容器资源
可以自定义所有 ContainerResource 子类以满足特定要求。 使用 托管集成 为容器资源建模但需要修改时,这非常有用。 当你拥有一个 IResourceBuilder<ContainerResource>
时,可以对任何可用的 API 进行链式调用,以修改该容器资源。
.NET
.NET Aspire 容器资源通常指向已固定的标记,但你可能想要改用 latest
标记。
为了更好地说明这个问题,请想象一个使用 .NET AspireRedis 集成的场景。 如果 Redis 集成依赖于 7.4
标记,并且想要改用 latest
标记,则可以串连调用 WithImageTag API:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache")
.WithImageTag("latest");
// Instead of using the "7.4" tag, the "cache"
// container resource now uses the "latest" tag.
有关更多信息和其他可用的 API,请参阅 ContainerResourceBuilderExtensions。
容器资源生命周期
运行应用主机时,ContainerResource 用于确定要创建和启动的容器映像。 在底层,.NET Aspire 使用定义的容器镜像,通过将调用委托给合适的符合 OCI 的容器运行时(Docker 或 Podman),来运行容器。 使用以下命令:
首先,使用 docker container create
命令创建容器。 然后,使用 docker container start
命令启动容器。
- docker 容器创建:从指定的映像创建新容器,而无需启动它。
- docker 容器启动:启动一个或多个已停止的容器。
这些命令用于代替 docker run
管理关联的容器网络、卷和端口。 按照此顺序调用这些命令,可以在初始启动时使任何 IP(网络配置)已经准备好。
除了基本资源类型、ProjectResource、ContainerResource和 ExecutableResource之外,.NET.NET Aspire 还提供扩展方法,用于向应用模型添加常见资源。 有关详细信息,请参阅 托管集成。
容器资源生存期
默认情况下,容器资源使用 会话 容器生存期。 这意味着,每次启动应用主机进程时,都会创建并启动容器。 当应用主机停止时,容器将停止并删除。 容器资源可以选择使用 持久性 生命周期,以避免不必要的重启并利用持久化的容器状态。 为此,请链式调用 ContainerResourceBuilderExtensions.WithLifetime API 并传递 ContainerLifetime.Persistent:
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddContainer("ollama", "ollama/ollama")
.WithLifetime(ContainerLifetime.Persistent);
前面的代码添加名为“ollama”的容器资源,其中包含图像“ollama/ollama”和持久生存期。
资源关系
资源关系将资源链接在一起。 关系是信息性的,不会影响应用的运行时行为。 而是在仪表板中显示有关资源的详细信息时使用它们。 例如,关系显示在 仪表板的资源详细信息中,而 Parent
关系控制资源嵌套在资源页面上。
关系由某些应用模型 API 自动创建。 例如:
-
WithReference 使用类型
Reference
向目标资源添加关系。 -
WaitFor 使用类型
WaitFor
向目标资源添加关系。 - 将数据库添加到 DB 容器将创建从数据库到具有类型
Parent
的容器的关系。
可以显式地将关系添加到应用模型中,使用 WithRelationship 和 WithParentRelationship。
var builder = DistributedApplication.CreateBuilder(args);
var catalogDb = builder.AddPostgres("postgres")
.WithDataVolume()
.AddDatabase("catalogdb");
builder.AddProject<Projects.AspireApp_CatalogDbMigration>("migration")
.WithReference(catalogDb)
.WithParentRelationship(catalogDb);
builder.Build().Run();
前面的示例使用 WithParentRelationship 将 catalogdb
数据库配置为 migration
项目的父级。
Parent
关系很特殊,因为它控制资源页面上的资源嵌套。 在此示例中,migration
嵌套在 catalogdb
下。
注释
有父子关系的验证可以防止资源具有多个父对象或创建循环引用。 无法在 UI 中呈现这些配置,应用模型将引发错误。