.NET Aspire Dapr 集成
分布式应用程序运行时(Dapr) 提供了开发人员 API,这些 API 充当与其他服务和依赖项交互的管道,并从这些服务和依赖项的特定内容中抽象化应用程序。 Dapr 和 .NET Aspire 可以协同工作,改善本地开发体验。 通过将 Dapr 与 .NET Aspire结合使用,可以专注于编写和实现基于 .NET的分布式应用程序,而不是本地载入。
本指南介绍如何利用 Dapr的抽象和 .NET Aspire的有意见配置云技术来大规模生成简单、可移植、可复原且安全的微服务。
比较 .NET Aspire 和 Dapr
乍一看,Dapr 和 .NET Aspire 似乎具有重叠的功能,确实如此。 但是,它们采用不同的方法。 .NET .NET Aspire 对如何在云平台上生成分布式应用程序并重点改进本地开发体验有意见。 Dapr 是一种运行时,用于在开发和生产过程中抽象化基础云平台的常见复杂性。 它依赖于 sidecars 为配置、机密管理和消息传送等内容提供抽象。 可以通过配置文件轻松切换基础技术,而代码不需要更改。
方面 | .NET Aspire | Dapr |
---|---|---|
目的 | 旨在更轻松地在本地开发计算机上开发云原生解决方案。 | 旨在更轻松地开发和运行具有可以轻松交换的常见 API 的分布式应用。 |
应用程序接口 | 开发人员必须使用其特定的 SDK 调用资源 API | 开发人员在 Dapr sidecar 中调用 API,后者将调用转发到正确的 API。 无需更改微服务中的代码即可轻松交换资源 API。 |
语言 | 可以使用 .NET 语言、Go、Python、Javascript 等语言编写微服务。 | 可以使用支持 HTTP/gRPC 接口的任何语言调用 Dapr sidecar 函数。 |
安全策略 | 不包括安全策略,但可以安全地配置依赖资源之间的连接。 | 包括可自定义的安全策略,用于控制哪些微服务有权访问其他服务或资源。 |
部署 | 有用于 Azure 和 Kubernetes的部署工具。 | 不包括部署工具。 应用通常使用持续集成/持续开发(CI/CD)系统进行部署。 |
仪表板 | 提供对资源及其遥测数据的全面视图,并支持侦听任何支持OTEL的资源。 | 仅限于 Dapr 资源。 |
.NET Aspire 通过提供简单的 API 来配置 Dapr 侧车,并将这些侧车作为资源显示在仪表板中,使设置和调试 Dapr 应用程序更加容易。
使用 Dapr 探索 .NET Aspire 组件
Dapr 提供了许多 内置组件,在 Dapr 与 .NET Aspire 一起使用时,可以轻松浏览和配置这些组件。 不要将这些组件与 .NET.NET Aspire 集成混淆。 例如,请考虑以下事项:
- Dapr— 状态存储:调用 AddDaprStateStore 将配置的状态存储添加到 .NET.NET Aspire 项目中。
- Dapr— Pub Sub:调用 AddDaprPubSub,将配置的 pub 子订阅添加到 .NET.NET Aspire 项目。
- Dapr— 组件:调用 AddDaprComponent,将已配置的集成添加到您的 .NET.NET Aspire 项目。
安装 Dapr
此集成需要 Dapr 1.13 或更高版本。 若要安装 Dapr,请参阅 安装 Dapr CLI。 安装 Dapr CLI 后,请运行 dapr init
,如本地环境中 初始化 Dapr 中所述。
重要
如果尝试在没有 Dapr CLI 的情况下运行 .NET Aspire 解决方案,将收到以下错误:
Unable to locate the Dapr CLI.
托管集成
在 .NET Aspire 解决方案中,为了集成 Dapr 并访问其类型和 API,请在 应用主机 项目中添加 📦Aspire.Hosting.Dapr NuGet 包。
dotnet add package Aspire.Hosting.Dapr
有关详细信息,请参阅 dotnet add package 或 管理 .NET 应用程序中的包依赖项。
将 Dapr sidecar 添加到 .NET Aspire 资源
Dapr 使用 侧车模式。 Dapr sidecar 作为轻量级、可移植和无状态 HTTP 服务器与应用一起运行,该服务器侦听来自应用的传入 HTTP 请求。
若要将 sidecar 添加到 .NET.NET Aspire 资源,请对它调用 WithDaprSidecar 方法。
appId
参数是 Dapr 应用程序的唯一标识符,但它是可选的。 如果未提供 appId
,则改用父资源名称。
using Aspire.Hosting.Dapr;
var builder = DistributedApplication.CreateBuilder(args);
var apiService = builder
.AddProject<Projects.Dapr_ApiService>("apiservice")
.WithDaprSidecar();
配置 Dapr sidecars
WithDaprSidecar
方法提供多种重载以配置 Dapr 的 sidecar 选项,例如 AppId
和不同的端口。 在以下示例中,Dapr sidecar 配置了用于 GRPC、HTTP、度量、以及特定应用 ID 的具体端口。
DaprSidecarOptions sidecarOptions = new()
{
AppId = "FirstSidecar",
DaprGrpcPort = 50001,
DaprHttpPort = 3500,
MetricsPort = 9090
};
builder.AddProject<Projects.Dapr_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(apiService)
.WithDaprSidecar(sidecarOptions);
完成 Dapr 应用主机示例
将所有内容组合在一起,请考虑以下 .NET.NET Aspire 应用主机项目的示例,其中包括:
- 一个后端 API 服务,用于声明具有默认值的 Dapr sidecar。
- 一个 Web 前端项目,用于声明具有特定选项的 Dapr 辅助进程,例如指定端口。
using Aspire.Hosting.Dapr;
var builder = DistributedApplication.CreateBuilder(args);
var apiService = builder
.AddProject<Projects.Dapr_ApiService>("apiservice")
.WithDaprSidecar();
DaprSidecarOptions sidecarOptions = new()
{
AppId = "FirstSidecar",
DaprGrpcPort = 50001,
DaprHttpPort = 3500,
MetricsPort = 9090
};
builder.AddProject<Projects.Dapr_Web>("webfrontend")
.WithExternalHttpEndpoints()
.WithReference(apiService)
.WithDaprSidecar(sidecarOptions);
builder.Build().Run();
启动 .NET Aspire 解决方案时,仪表板将显示 Dapr 侧车作为资源,其状态和日志。
显示
在使用 .NET Aspire 项目中使用 Dapr sidecar
若要从 .NET Aspire 资源使用 Dapr API,可以使用 📦Dapr的 .AspNetCore/ NuGet 包。 Dapr SDK 提供了一组 API 来与 Dapr sidecars 进行交互。
注意
使用 Dapr.AspNetCore
库进行 Dapr 与 ASP.NET 的集成(DI 集成、订阅注册等)。 非ASP.NET 应用(如控制台应用)只能使用 📦Dapr。Client 通过 Dapr 侧车进行呼叫。
dotnet add package Dapr.AspNetCore
添加 Dapr 客户端
安装到 ASP.NET Core 项目中后,可以将 SDK 添加到服务生成器。
builder.Services.AddDaprClient();
调用 Dapr 方法
现可将 DaprClient
实例注入到您的服务中,通过 Dapr SDK 与 Dapr sidecar 交互。
using Dapr.Client;
namespace Dapr.Web;
public class WeatherApiClient(DaprClient client)
{
public async Task<WeatherForecast[]> GetWeatherAsync(
int maxItems = 10, CancellationToken cancellationToken = default)
{
List<WeatherForecast>? forecasts =
await client.InvokeMethodAsync<List<WeatherForecast>>(
HttpMethod.Get,
"apiservice",
"weatherforecast",
cancellationToken);
return forecasts?.Take(maxItems)?.ToArray() ?? [];
}
}
public record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
InvokeMethodAsync
是向 Dapr sidecar 发送 HTTP 请求的方法。 它是一种泛型方法,需要:
- HTTP 动词。
- 要调用的服务 Dapr 应用 ID。
- 方法名称。
- 取消令牌。
根据 HTTP 谓词,它还可以接收请求正文和标头。 泛型类型参数是响应正文的类型。
前端项目的完整 Program.cs 文件显示:
- 在服务生成器中添加 Dapr 客户端。
- 使用 Dapr 客户端的
WeatherApiClient
类来调用后端服务。
using Dapr.Web;
using Dapr.Web.Components;
var builder = WebApplication.CreateBuilder(args);
// Add service defaults & Aspire components.
builder.AddServiceDefaults();
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddOutputCache();
builder.Services.AddDaprClient();
builder.Services.AddTransient<WeatherApiClient>();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.UseOutputCache();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.MapDefaultEndpoints();
app.Run();
例如,在 Blazor 项目中,可以将 WeatherApiClient
类注入到 razor 页面中,并使用它调用后端服务:
@page "/weather"
@attribute [StreamRendering(true)]
@attribute [OutputCache(Duration = 5)]
@inject WeatherApiClient WeatherApi
<PageTitle>Weather</PageTitle>
<h1>Weather</h1>
<p>This component demonstrates showing data loaded from a backend API service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[]? forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await WeatherApi.GetWeatherAsync();
}
}
使用 Dapr SDK 时,会通过 HTTP 调用 Dapr sidecar。 然后,Dapr sidecar 将请求转发到目标服务。 虽然目标服务在与 sidecar 的单独进程中运行,但与服务相关的集成在 Dapr sidecar 中运行,并负责服务发现并将请求路由到目标服务。