.NET .NET Aspire 協調流程概觀
.NET .NET Aspire 提供 API 來表達分散式應用程式內的資源和相依性。 除了這些 API 之外,還有一些工具 可以支援數個引人注目的場景。 協調器用於 本機開發 目的,而且不支援在生產環境中使用。
在繼續之前,請考慮 .NET.NET Aspire中使用的一些常見術語:
- 應用程式模型:組成分散式應用程式的資源集合(DistributedApplication),定義於 Aspire.Hosting.ApplicationModel 命名空間內。 如需更正式的定義,請參閱 定義應用程式模型。
- 應用程式主機/Orchestrator 專案:以 .NET 後綴(依照慣例)命名的 專案,負責協調 應用程式模型。
- 資源:資源 是應用程式的相依部分,例如 .NET 專案、容器、可執行檔、資料庫、快取或雲端服務。 它代表可以管理或參考之應用程式的任何部分。
- 整合:整合可以是 應用程式主機 的 NuGet 套件,用來建構 資源 模型;或者是用於在取用應用程式中的設定 client 的套件。 如需詳細資訊,請參閱 .NET.NET Aspire 整合概觀。
- 參考:參考會定義資源之間的關係,以相依性表示,使用 WithReference API。 如需詳細資訊,請參閱 參考資源 或 參考現有資源。
注意
.NET .NET Aspire的協調流程旨在藉由簡化雲端原生應用程式的設定和互連的管理,來增強 本機開發 體驗。 雖然它是一個寶貴的開發工具,但它並不是用來取代生產環境系統,例如 Kubernetes,這些系統特別設計在該環境中表現出色。
定義應用程式模型
.NET .NET Aspire 可讓您順暢地建置、布建、部署、設定、測試、執行及觀察分散式應用程式。 所有這些功能都是透過利用 應用程式模型, 來概述 .NET.NET Aspire 解決方案及其關聯性中的資源。 這些資源包含專案、可執行檔、容器,以及應用程式相依的外部服務和雲端資源。 在每個 .NET.NET Aspire 解決方案中,有一個指定的 App 主專案,其中應用程式模型會使用 IDistributedApplicationBuilder上可用的方法來精確定義。 這個建構器是藉由叫用 DistributedApplication.CreateBuilder來取得。
// Create a new app model builder
var builder = DistributedApplication.CreateBuilder(args);
// TODO:
// Add resources to the app model
// Express dependencies between resources
builder.Build().Run();
應用程式主機專案
應用程式主項目會處理執行屬於 .NET.NET Aspire 專案的所有專案。 換句話說,它負責協調應用程式模型內的所有應用程式。 專案本身是參考 .NET📦的 Aspire 可執行專案。Hosting.AppHost NuGet 套件、將 IsAspireHost
屬性設定為 true
,並參考 .NET.NET Aspire SDK:
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<IsAspireHost>true</IsAspireHost>
<!-- Omitted for brevity -->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
</ItemGroup>
<!-- Omitted for brevity -->
</Project>
下列程式碼描述了應用程式主機 Program
,該主機具有兩個項目參考,以及一個 Redis 快取:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(cache)
.WaitFor(cache)
.WithReference(apiService)
.WaitFor(apiService);
builder.Build().Run();
上述程式代碼:
- 使用 CreateBuilder 方法建立新的應用程式模型建立器。
- 使用 Redis 方法,新增名為 「cache」 的
cache
AddRedis 資源。 - 使用 AddProject 方法新增名為 「apiservice」 的項目資源。
- 使用 AddProject 方法新增名為 「webfrontend」 的項目資源。
- 指定專案具有使用 WithExternalHttpEndpoints 方法的外部 HTTP 端點。
- 新增
cache
資源的參考,並等候它準備好使用 WithReference 和 WaitFor 方法。 - 新增
apiservice
資源的參考,並等候它準備好使用 WithReference 和 WaitFor 方法。
- 使用 Build 和 Run 方法來建置並執行應用程式模型。
範例程式代碼會使用主機整合 .NET AspireRedis。
若要協助將應用程式主機專案與其描述的資源之間的關聯性可視化,請考慮下圖:
每個資源都必須以唯一方式命名。 此圖顯示每個資源及其之間的關聯性。 容器資源名為“cache”,專案資源的名稱為 “apiservice” 和 “webfrontend”。 Web 前端項目會參考快取和 API 服務專案。 當您以這種方式表達參考時,網站前端專案會指出其相依於這兩個資源,分別是「快取」和「API 服務」。
內建資源類型
.NET .NET Aspire 專案是由一組資源所組成。 在 📦Aspire中, NuGet 套件的 Hosting.AppHost 主要基底資源類型於下表中說明:
方法 | 資源類型 | 描述 |
---|---|---|
AddProject | ProjectResource | .NET 專案,例如 ASP.NET Core Web 應用程式。 |
AddContainer | ContainerResource | 容器映像檔,例如 Docker 映像檔。 |
AddExecutable | ExecutableResource | 可執行檔案,例如 Node.js 應用程式。 |
AddParameter | ParameterResource | 參數資源,可用來 表示外部參數。 |
項目資源代表屬於應用程式模型的 .NET 專案。 當您將項目參考新增至應用程式主專案時,.NET.NET Aspire SDK 會在每個參考專案的 Projects
命名空間中產生類型。 如需詳細資訊,請參閱 .NET.NET Aspire SDK:項目參考。
若要將專案新增至應用程式模型,請使用 AddProject 方法:
var builder = DistributedApplication.CreateBuilder(args);
// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
您可以透過將相同專案的多個實例新增至應用程式模型,以複製並擴展專案的規模。 若要設定複本,請使用 WithReplicas 方法:
var builder = DistributedApplication.CreateBuilder(args);
// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReplicas(3);
上述程式代碼會將 「apiservice」 項目資源的三個複本新增至應用程式模型。 如需詳細資訊,請參閱 .NET.NET Aspire 儀表板:資源復本。
參考資源
參考代表資源之間的相依性。 例如,您可能會想像一個 Web 前端必須依賴 Redis 快取的情境。 請考慮下列範例應用程式主機 Program
C# 程式代碼:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache);
“webfrontend” 專案資源會使用 WithReference 來新增「快取」容器資源的相依性。 這些相依性可以代表連接字串或 服務探索 資訊。 在上述範例中,環境變數 ConnectionStrings__cache
。 此環境變數包含連接字串,webfrontend
用來透過 Redis連線到 ,例如,ConnectionStrings__cache="localhost:62354"
。
等候資源
在某些情況下,您可能想要等候資源準備好,再啟動另一個資源。 例如,您可能想要等候資料庫準備好,再啟動相依於資料庫的 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 主機整合 和 client 整合 都以 NuGet 套件形式提供,但用途不同。 雖然 client 整合 提供 client 連結庫組態來取用應用程式主機以外的應用程式,裝載整合 提供 API 來表示應用程式主機內的資源和相依性。 如需詳細資訊,請參閱 .NET.NET Aspire 整合概觀:整合責任。
Express 容器資源
若要表示 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殼層腳本的入口點,以及具有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」 和持續性存留期。
連接字串和端點參考
通常表示專案資源之間的相依性。 請考慮下列範例程式代碼:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiservice);
專案間參考的處理方式與具有定義良好連接字串的資源的處理不同。 插入 「webfrontend」 資源時,會插入支援服務探索的環境變數,而不是插入連接字串。
方法 | 環境變數 |
---|---|
WithReference(cache) |
ConnectionStrings__cache="localhost:62354" |
WithReference(apiservice) |
services__apiservice__http__0="http://localhost:5455" services__apiservice__https__0="https://localhost:7356" |
將「apiservice」專案新增為參考,會使服務探索環境變數新增至前端。 這是因為通常透過 HTTP/gRPC 進行項目對項目通訊。 如需詳細資訊,請參閱 .NET.NET Aspire 服務探索。
若要從 ContainerResource 或 ExecutableResource取得特定端點,請使用下列其中一個端點 API:
然後呼叫 GetEndpoint API 以取得端點,以便在 WithReference
方法中引用該端點:
var builder = DistributedApplication.CreateBuilder(args);
var customContainer = builder.AddContainer("myapp", "mycustomcontainer")
.WithHttpEndpoint(port: 9043, name: "endpoint");
var endpoint = customContainer.GetEndpoint("endpoint");
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(endpoint);
方法 | 環境變數 |
---|---|
WithReference(endpoint) |
services__myapp__endpoint__0=https://localhost:9043 |
port
參數是容器正在接聽的埠。 如需容器埠的詳細資訊,請參閱 容器埠。 如需服務探索的詳細資訊,請參閱 .NET.NET Aspire 服務探索。
服務端點環境變數格式
在上一節中,會使用 WithReference 方法來表示資源之間的相依性。 當服務端點使得環境變數被插入到相依資源中時,格式可能不容易看出。 本節提供此格式的詳細數據。
當某個資源相依於另一個資源時,應用程式主機會將環境變數插入相依資源。 這些環境變數設定相依資源以連接到其所依賴的資源。 環境變數的格式專屬於 .NET.NET Aspire,並以與 Service Discovery相容的方式表示服務端點。
服務端點環境變數名稱前面會加上 services__
(雙底線),然後是服務名稱、端點名稱,最後是索引。 索引支援單一服務的多個端點,從第一個端點的 0
開始,並針對每個端點遞增。
請考慮下列環境變數範例:
services__apiservice__http__0
上述環境變數表示 apiservice
服務的第一個 HTTP 端點。 環境變數的值是服務端點的URL。 具名端點可能會以下列方式表示:
services__apiservice__myendpoint__0
在上述範例中,apiservice
服務具有名為 myendpoint
的具名端點。 環境變數的值是服務端點的URL。
參考現有的資源
在某些情況下,您應該參考現有的資源,這些資源可能是部署到雲端提供者的。 例如,您可能想要參考 Azure 資料庫。 在此情況下,您可以依靠 執行環境 來動態判斷應用程式主機是以「執行」模式或「發佈」模式運行。 如果您要在本機執行並想要依賴雲端資源,您可以使用 IsRunMode
屬性來有條件地新增參考。 您可以選擇改為在發佈模式中建立資源。 有些 主機整合功能 支援提供直接的連接字串,可用來參考現有的資源。
同樣地,可能會有需要將 .NET.NET Aspire 整合至現有解決方案的使用情境。 其中一個常見方法是將 .NET.NET Aspire 應用程式主專案新增至現有的解決方案。 在應用程式主機內,您會將專案參考新增至應用程式主機,並 建置應用程式模型來表示相依性。 例如,某個專案可能相依於另一個專案。 這些相依性會使用 WithReference 方法來表示。 如需詳細資訊,請參閱 將 .NET Aspire 新增至現有的 .NET 應用程式。
應用程式主機生命週期
.NET .NET Aspire 應用程式主機會公開數個生命週期,您可以藉由實作 IDistributedApplicationLifecycleHook 介面來連結。 下列生命週期方法可供使用:
次序 | 方法 | 描述 |
---|---|---|
1 | BeforeStartAsync | 在分散式應用程式啟動之前執行。 |
2 | AfterEndpointsAllocatedAsync | 協調器在為應用程式模型中的資源分配端點後執行。 |
3 | AfterResourcesCreatedAsync | 在協調器已建立資源後進行執行。 |
雖然應用程式主機提供生命週期掛勾,但您可以註冊自定義事件。 如需詳細資訊,請參閱
註冊生命週期掛勾
若要註冊生命周期掛鉤,請實作 IDistributedApplicationLifecycleHook 介面,並使用 AddLifecycleHook API 將該掛鉤註冊到應用程式主機。
using Aspire.Hosting.Lifecycle;
using Microsoft.Extensions.Logging;
var builder = DistributedApplication.CreateBuilder(args);
builder.Services.AddLifecycleHook<LifecycleLogger>();
builder.Build().Run();
internal sealed class LifecycleLogger(ILogger<LifecycleLogger> logger)
: IDistributedApplicationLifecycleHook
{
public Task BeforeStartAsync(
DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
{
logger.LogInformation("BeforeStartAsync");
return Task.CompletedTask;
}
public Task AfterEndpointsAllocatedAsync(
DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
{
logger.LogInformation("AfterEndpointsAllocatedAsync");
return Task.CompletedTask;
}
public Task AfterResourcesCreatedAsync(
DistributedApplicationModel appModel, CancellationToken cancellationToken = default)
{
logger.LogInformation("AfterResourcesCreatedAsync");
return Task.CompletedTask;
}
}
上述程式代碼:
- 實作 IDistributedApplicationLifecycleHook 介面做為
LifecycleLogger
。 - 使用 AddLifecycleHook API 向應用程式主機註冊生命周期連結。
- 記錄所有事件的訊息。
當執行此應用程式主機時,會針對每個事件執行生命週期掛勾。 會產生下列輸出:
info: LifecycleLogger[0]
BeforeStartAsync
info: Aspire.Hosting.DistributedApplication[0]
Aspire version: 9.0.0
info: Aspire.Hosting.DistributedApplication[0]
Distributed application starting.
info: Aspire.Hosting.DistributedApplication[0]
Application host directory is: ..\AspireApp\AspireApp.AppHost
info: LifecycleLogger[0]
AfterEndpointsAllocatedAsync
info: Aspire.Hosting.DistributedApplication[0]
Now listening on: https://localhost:17043
info: Aspire.Hosting.DistributedApplication[0]
Login to the dashboard at https://localhost:17043/login?t=d80f598bc8a64c7ee97328a1cbd55d72
info: LifecycleLogger[0]
AfterResourcesCreatedAsync
info: Aspire.Hosting.DistributedApplication[0]
Distributed application started. Press Ctrl+C to shut down.
連結至應用程式主機生命週期的慣用方式是使用事件 API。 如需詳細資訊,請參閱
執行上下文
IDistributedApplicationBuilder 會揭露執行環境(DistributedApplicationExecutionContext),以提供應用程式主機目前執行的相關資訊。 此內容可用來評估應用程式主機是否以「執行」模式執行,或作為發佈作業的一部分。 請考慮下列屬性:
-
IsRunMode:如果目前作業正在執行,則傳回
true
。 -
IsPublishMode:如果目前正在發佈作業,則傳回
true
。
當您想要根據目前作業有條件地執行程式碼時,這項資訊很有用。 請考慮下列範例,示範如何使用 IsRunMode
屬性。 在此情況下,擴充方法用來為本地開發執行的 RabbitMQ 產生穩定的節點名稱。
private static IResourceBuilder<RabbitMQServerResource> RunWithStableNodeName(
this IResourceBuilder<RabbitMQServerResource> builder)
{
if (builder.ApplicationBuilder.ExecutionContext.IsRunMode)
{
builder.WithEnvironment(context =>
{
// Set a stable node name so queue storage is consistent between sessions
var nodeName = $"{builder.Resource.Name}@localhost";
context.EnvironmentVariables["RABBITMQ_NODENAME"] = nodeName;
});
}
return builder;
}
執行內容通常用來有條件地新增指向現有資源的資源或連接字串。 請考慮下列範例,示範根據執行內容有條件地新增 Redis 或連接字串:
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.ExecutionContext.IsRunMode
? builder.AddRedis("redis")
: builder.AddConnectionString("redis");
builder.AddProject<Projects.WebApplication>("api")
.WithReference(redis);
builder.Build().Run();
在上述程式代碼中:
- 如果應用程式主機以「執行」模式執行,則會新增 Redis 容器資源。
- 如果應用程式主機以「發佈」模式執行,則會新增連接字串。
當您在本機執行時,可以輕鬆地反轉此邏輯來連線到現有的 Redis 資源,並在發佈時建立新的 Redis 資源。
重要
.NET
.NET Aspire 提供常見的 API 來控制資源產生器的形式,讓資源根據執行模式以不同的方式運作。 Fluent API 前面會加上 RunAs*
和 PublishAs*
。
RunAs*
API 會影響本機開發(或執行模式)行為,而 PublishAs*
API 會影響資源的發佈。