.NET Aspire提供了一种简化的方法,用于生成支持 Orleans 的云原生应用程序。 从 Orleans 8.0 开始,可以使用 Aspire 来协调 Orleans 群集、管理支持资源(如 Redis 或 Azure 存储),并自动配置服务发现、可观测性和运行状况检查。
概述
若要在 AppHost 项目中实现 Orleans 与 .NET Aspire 的集成,需要使用 Aspire.Hosting.Orleans 包。 此包提供扩展方法,以便:
- 将 Orleans 定义为分布式资源
- 配置群集提供程序(Redis、Azure 存储、ADO.NET)
- 配置粒度存储提供程序
- 配置提醒提供程序
- 配置粒度目录服务提供程序
- 模型孤岛和客户端关系
先决条件
在使用Orleans与Aspire之前,请确保具备:
- .NET 8.0 SDK 或更高版本
- .NET Aspire 工作负荷
- 具有 Aspire 支持的 IDE(Visual Studio 2022 17.9+、带有 C# 开发工具包的 VS Code 或 JetBrains Rider)
必需包
您的解决方案需要以下软件包引用:
AppHost 项目
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.1.3" />
<PackageReference Include="Aspire.Hosting.Orleans" Version="13.1.3" />
<PackageReference Include="Aspire.Hosting.Redis" Version="13.1.3" />
</ItemGroup>
Orleans 筒仓项目
<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Server" Version="10.1.0" />
<PackageReference Include="Microsoft.Orleans.Clustering.Redis" Version="10.1.0" />
<PackageReference Include="Aspire.StackExchange.Redis" Version="13.2.4" />
</ItemGroup>
Orleans 客户端项目(如果独立于 silo)
<ItemGroup>
<PackageReference Include="Microsoft.Orleans.Client" Version="10.1.0" />
<PackageReference Include="Microsoft.Orleans.Clustering.Redis" Version="10.1.0" />
<PackageReference Include="Aspire.StackExchange.Redis" Version="13.2.4" />
</ItemGroup>
配置 AppHost
AppHost 项目协调 Orleans 群集及其依赖项。
启用了 Redis 群集功能的基本 Orleans 群集
public static void BasicOrleansCluster(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
// Add Redis for Orleans clustering
var redis = builder.AddRedis("orleans-redis");
// Define the Orleans resource with Redis clustering
var orleans = builder.AddOrleans("cluster")
.WithClustering(redis);
// Add the Orleans silo project
builder.AddProject<Projects.Silo>("silo")
.WithReference(orleans)
.WaitFor(redis)
.WithReplicas(3);
builder.Build().Run();
}
Orleans 包含粒度存储和提醒
public static void OrleansWithStorageAndReminders(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.AddRedis("orleans-redis");
var orleans = builder.AddOrleans("cluster")
.WithClustering(redis)
.WithGrainStorage("Default", redis)
.WithGrainStorage("PubSubStore", redis)
.WithReminders(redis);
builder.AddProject<Projects.Silo>("silo")
.WithReference(orleans)
.WaitFor(redis)
.WithReplicas(3);
builder.Build().Run();
}
独立的 silo 和客户端项目
当 Orleans 客户端在单独的进程(如 Web 前端)中运行时,请使用 .AsClient() 以下方法:
public static void SeparateSiloAndClient(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.AddRedis("orleans-redis");
var orleans = builder.AddOrleans("cluster")
.WithClustering(redis)
.WithGrainStorage("Default", redis);
// Backend Orleans silo cluster
var silo = builder.AddProject<Projects.Silo>("backend")
.WithReference(orleans)
.WaitFor(redis)
.WithReplicas(5);
// Frontend web project as Orleans client
builder.AddProject<Projects.Client>("frontend")
.WithReference(orleans.AsClient()) // Client-only reference
.WaitFor(silo);
builder.Build().Run();
}
配置 Orleans silo 项目
在Orleans孤立项目中,配置Orleans以使用Aspire提供的资源:
public static void BasicSiloConfiguration(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
// Add Aspire service defaults (OpenTelemetry, health checks, etc.)
builder.AddServiceDefaults();
// Add the Aspire Redis client for Orleans
builder.AddKeyedRedisClient("orleans-redis");
// Configure Orleans - Aspire injects all configuration automatically
builder.UseOrleans();
builder.Build().Run();
}
小窍门
使用 .NET Aspire 时,无参数的 UseOrleans 通常是你需要的。
Aspire通过环境变量向Orleans注入配置(群集 ID、服务 ID、终结点和提供程序设置),这些变量将被Orleans自动读取。 仅当你需要执行 Aspire 所提供功能之外的其他手动配置时,才需要使用委托重载 UseOrleans(siloBuilder => {...})。
重要
必须调用适当的 AddKeyed* 方法(例如 AddKeyedRedisClient, AddKeyedAzureTableClient或 AddKeyedAzureBlobClient)在依赖项注入容器中注册支持资源。
Orleans 提供程序按其键型服务名称查找资源 — 如果跳过此步骤, Orleans 将无法解析资源,并在运行时引发依赖项解析错误。 这适用于由Aspire托管并与Orleans一起使用的所有资源。
使用显式连接字符串进行配置
如果需要显式控制连接字符串,可以从配置中读取它:
public static void ExplicitConnectionConfiguration(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
builder.AddServiceDefaults();
builder.AddKeyedRedisClient("orleans-redis");
builder.UseOrleans(siloBuilder =>
{
var redisConnectionString = builder.Configuration.GetConnectionString("orleans-redis");
siloBuilder.UseRedisClustering(options =>
{
options.ConfigurationOptions =
ConfigurationOptions.Parse(redisConnectionString!);
});
siloBuilder.AddRedisGrainStorageAsDefault(options =>
{
options.ConfigurationOptions =
ConfigurationOptions.Parse(redisConnectionString!);
});
});
builder.Build().Run();
}
配置Orleans客户端项目
对于单独的客户端项目,请类似地配置 Orleans 客户端:
public static void BasicClientConfiguration(string[] args)
{
var builder = Host.CreateApplicationBuilder(args);
builder.AddServiceDefaults();
builder.AddKeyedRedisClient("orleans-redis");
// Configure Orleans client - Aspire injects clustering configuration automatically
builder.UseOrleansClient();
builder.Build().Run();
}
AppHost 扩展方法参考
该 Aspire.Hosting.Orleans 包提供以下扩展方法:
核心方法
| 方法 | Description |
|---|---|
builder.AddOrleans(name) |
Orleans将资源添加到具有指定名称的分布式应用程序。 |
.WithClusterId(id) |
设置Orleans的 ClusterId。 接受字符串或 ParameterResource。 如果未指定,则自动生成唯一 ID。 |
.WithServiceId(id) |
设置Orleans ServiceId。 接受字符串或 ParameterResource。 如果未指定,则自动生成唯一 ID。 |
.AsClient() |
返回对 Orleans 资源的仅限客户端引用(不包括 silo 功能)。 |
project.WithReference(orleans) |
将 Orleans 资源引用添加到项目,从而启用配置注入。 |
注释
使用或类似方法配置后备资源.WithClustering(resource).WithGrainStorage(name, resource)时,Orleans资源会自动包含对该后备资源的引用。 您不需要单独为每个后备资源调用 .WithReference() ,只需调用 .WithReference(orleans)。 但是,你应该在支持资源上使用 .WaitFor(),以确保它在 silo 启动之前准备就绪。
Clustering
| 方法 | Description |
|---|---|
.WithClustering(resource) |
将 Orleans 群集配置为使用指定的资源(Redis、Azure 存储、Cosmos DB 等)。 |
.WithDevelopmentClustering() |
仅为本地开发配置内存中的单主机群集。 不适合用于生产。 |
粮食存储
| 方法 | Description |
|---|---|
.WithGrainStorage(name, resource) |
使用指定的资源配置命名粒度存储提供程序。 |
.WithMemoryGrainStorage(name) |
为指定名称配置内存中粒度存储。 数据孤岛重启时数据会丢失。 |
提醒事项
| 方法 | Description |
|---|---|
.WithReminders(resource) |
使用指定资源配置Orleans提醒服务。 |
.WithMemoryReminders() |
为开发配置内存中存储的提醒。 在 silo 重启时,提醒会丢失。 |
流媒体
| 方法 | Description |
|---|---|
.WithStreaming(name, resource) |
使用指定的资源(例如 Azure 队列存储)配置命名流提供程序。 |
.WithMemoryStreaming(name) |
配置内存内流式处理以用于开发。 |
.WithBroadcastChannel(name) |
配置具有指定名称的广播通道提供程序。 |
Grain目录
| 方法 | Description |
|---|---|
.WithGrainDirectory(name, resource) |
使用指定的资源配置命名粒度目录。 |
服务默认值模式
Aspire 使用 ServiceDefaults 项目模式在所有项目中共享通用配置。 对于 Orleans,这通常包括:
OpenTelemetry 配置
public static IHostApplicationBuilder AddServiceDefaults(
this IHostApplicationBuilder builder)
{
builder.ConfigureOpenTelemetry();
builder.AddDefaultHealthChecks();
return builder;
}
public static IHostApplicationBuilder ConfigureOpenTelemetry(
this IHostApplicationBuilder builder)
{
builder.Logging.AddOpenTelemetry(logging =>
{
logging.IncludeFormattedMessage = true;
logging.IncludeScopes = true;
});
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRuntimeInstrumentation()
.AddMeter("Microsoft.Orleans"); // Orleans metrics
})
.WithTracing(tracing =>
{
tracing.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddSource("Microsoft.Orleans.Runtime")
.AddSource("Microsoft.Orleans.Application");
});
return builder;
}
使用Aspire 的 Azure 存储
可以使用 Azure 存储资源实现 Orleans 群集功能和持久性:
public static void AzureStorageWithAspire(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
// Add Azure Storage for Orleans
var storage = builder.AddAzureStorage("orleans-storage")
.RunAsEmulator(); // Use Azurite emulator for local development
var tables = storage.AddTables("orleans-tables");
var blobs = storage.AddBlobs("orleans-blobs");
var orleans = builder.AddOrleans("cluster")
.WithClustering(tables)
.WithGrainStorage("Default", blobs)
.WithReminders(tables);
builder.AddProject<Projects.Silo>("silo")
.WithReference(orleans)
.WaitFor(storage)
.WithReplicas(3);
builder.Build().Run();
}
开发与生产配置
Aspire 可以轻松地在开发和生产配置之间进行切换:
本地开发(使用模拟器)
public static void LocalDevelopment(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
var redis = builder.AddRedis("orleans-redis");
// Redis container runs automatically during development
var orleans = builder.AddOrleans("cluster")
.WithClustering(redis);
// ...
}
生产(使用托管服务)
public static void ProductionConfig(string[] args)
{
var builder = DistributedApplication.CreateBuilder(args);
// Use existing Azure Cache for Redis
var redis = builder.AddConnectionString("orleans-redis");
var orleans = builder.AddOrleans("cluster")
.WithClustering(redis);
// ...
}
健康检查
Aspire 会自动配置运行状况检查端点。 可以添加特定于 Orleans 的运行状况检查:
public static void ConfigureHealthChecks(IHostApplicationBuilder builder)
{
builder.Services.AddHealthChecks()
.AddCheck<GrainHealthCheck>("orleans-grains")
.AddCheck<SiloHealthCheck>("orleans-silo");
}
最佳做法
使用 ServiceDefaults 项目:通过 ServiceDefaults 项目在所有项目中共享通用配置(如 OpenTelemetry 和运行状况检查)。
等待依赖项:始终使用
.WaitFor()确保支持资源(Redis、数据库)在 Orleans silo 启动之前准备就绪。配置副本:使用
.WithReplicas()运行多个孤岛实例,以实现容错和可扩展性。独立的客户端项目:对于 Web 前端,请使用
.AsClient()来配置 Orleans 的仅客户端模式。使用模拟器进行开发:Aspire可以使用容器在本地运行 Redis、Azure 存储(Azurite)和其他依赖项。
启用分布式跟踪:使用 Orleans 源名称配置 OpenTelemetry 以跟踪群集中的粒度调用。
另请参阅
.NET Aspire 集成是在 Orleans 8.0 中引入的。 对于 Orleans 7.0,你仍然可以部署到由 Aspire 协调的环境,但专用 Aspire.Hosting.Orleans 包及其扩展方法不可用。
请考虑升级到 Orleans 8.0 或更高版本以利用 Aspire 集成功能。
.NET Aspire 集成在 Orleans 8.0 及更高版本中提供。 Orleans 3.x 不支持 .NET Aspire。