关于 akka-net-management
面向 Akka.NET 的管理与集群引导配置技能,帮助开发者在 Kubernetes 等动态环境中设置服务发现、集群组建和健康端点。
主要功能
- 01动态集群发现
- 02配置集群引导
- 03HTTP 管理端点
- 04存活与就绪检查
- 05Config、Kubernetes 与 Azure 发现
适用场景
- 01在 Kubernetes 中替换静态种子节点
- 02配置自动扩缩环境中的集群
- 03向负载均衡器提供健康检查
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ aaronontheweb/ dotnet-skills --skill akka-net-management安装后在 Claude Code 中输入/akka-net-management确认已加载。
附带文件configuration-reference.mddiscovery-providers.md
详细介绍
Akka.NET 管理与服务发现
何时使用此技能
在以下情况下使用此技能:
- 将 Akka.NET 集群部署到 Kubernetes 或云环境
- 使用动态服务发现替代静态种子节点
- 配置集群引导以实现自动组建
- 为负载均衡器设置健康检查端点
- 集成 Azure Table Storage、Kubernetes API 或基于配置的发现
参考文件
- discovery-providers.md:Config、Kubernetes 和 Azure 发现配置,包含完整代码和部署 YAML
- configuration-reference.md:强类型配置模型类
概述
Akka.Management 提供集群管理 HTTP 端点,并与 Akka.Cluster.Bootstrap 集成,通过服务发现而非静态种子节点实现动态集群组建。
为什么使用 Akka.Management?
| 方式 | 优点 | 缺点 |
|---|---|---|
| 静态种子节点 | 简单,无依赖 | 无法扩展,需要已知 IP |
| Akka.Management | 动态发现,可扩展至 N 个节点 | 配置较多,有外部依赖 |
以下场景使用静态种子节点:开发、单节点部署、固定基础设施。
以下场景使用 Akka.Management:Kubernetes、自动扩缩组、动态环境、生产集群。
架构
┌─────────────────────────────────────────────────────────────┐
│ Cluster Bootstrap │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │
│ │ │ │ │ │ │ │
│ │ Management │◄──►│ Management │◄──►│ Management │ │
│ │ HTTP :8558 │ │ HTTP :8558 │ │ HTTP :8558 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └──────────────────┼──────────────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Discovery │ │
│ │ Provider │ │
│ └───────────────┘ │
│ │ │
└────────────────────────────┼────────────────────────────────┘
│
┌──────────────┼──────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼─────┐ ┌─────▼──────┐
│ Kubernetes│ │ Azure │ │ Config │
│ API │ │ Tables │ │ (HOCON) │
└───────────┘ └────────────┘ └────────────┘
必需的 NuGet 包
<ItemGroup>
<PackageReference Include="Akka.Management" />
<PackageReference Include="Akka.Management.Cluster.Bootstrap" />
<PackageReference Include="Akka.Discovery.KubernetesApi" />
<PackageReference Include="Akka.Discovery.Azure" />
<PackageReference Include="Akka.Discovery.Config.Hosting" />
</ItemGroup>
Akka.Hosting 配置
基本设置与模式选择
public static class AkkaConfiguration
{
public static IServiceCollection ConfigureAkka(
this IServiceCollection services,
Action<AkkaConfigurationBuilder, IServiceProvider>? additionalConfig = null)
{
services.AddOptions<AkkaSettings>()
.BindConfiguration("AkkaSettings")
.ValidateDataAnnotations()
.ValidateOnStart();
return services.AddAkka("MySystem", (builder, sp) =>
{
var settings = sp.GetRequiredService<IOptions<AkkaSettings>>().Value;
var configuration = sp.GetRequiredService<IConfiguration>();
ConfigureNetwork(builder, settings, configuration);
ConfigureHealthChecks(builder);
additionalConfig?.Invoke(builder, sp);
});
}
private static void ConfigureNetwork(
AkkaConfigurationBuilder builder,
AkkaSettings settings,
IConfiguration configuration)
{
if (settings.ExecutionMode == AkkaExecutionMode.LocalTest)
return;
builder.WithRemoting(settings.RemoteOptions);
if (settings.ClusterBootstrapOptions.Enabled)
ConfigureAkkaManagement(builder, settings, configuration);
else
builder.WithClustering(settings.ClusterOptions);
}
}
Akka.Management 配置
private static void ConfigureAkkaManagement(
AkkaConfigurationBuilder builder,
AkkaSettings settings,
IConfiguration configuration)
{
var mgmtOptions = settings.AkkaManagementOptions;
var bootstrapOptions = settings.ClusterBootstrapOptions;
// IMPORTANT: Clear seed nodes when using Akka.Management
settings.ClusterOptions.SeedNodes = [];
builder
.WithClustering(settings.ClusterOptions)
.WithAkkaManagement(setup =>
{
setup.Http.HostName = mgmtOptions.HostName;
setup.Http.Port = mgmtOptions.Port;
setup.Http.BindHostName = "0.0.0.0";
setup.Http.BindPort = mgmtOptions.Port;
})
.WithClusterBootstrap(options =>
{
options.ContactPointDiscovery.ServiceName = bootstrapOptions.ServiceName;
options.ContactPointDiscovery.PortName = bootstrapOptions.PortName;
options.ContactPointDiscovery.RequiredContactPointsNr = bootstrapOptions.RequiredContactPointsNr;
options.ContactPointDiscovery.Interval = bootstrapOptions.ContactPointProbingInterval;
options.ContactPointDiscovery.StableMargin = bootstrapOptions.StableMargin;
options.ContactPointDiscovery.ContactWithAllContactPoints = bootstrapOptions.ContactWithAllContactPoints;
options.ContactPoint.FilterOnFallbackPort = bootstrapOptions.FilterOnFallbackPort;
options.ContactPoint.ProbeInterval = bootstrapOptions.BootstrapperDiscoveryPingInterval;
});
// Configure the discovery provider
ConfigureDiscovery(builder, settings, configuration);
}
请参阅 discovery-providers.md,获取完整的 Config、Kubernetes 和 Azure 发现配置代码。
请参阅 configuration-reference.md,获取完整的强类型配置模型类。
健康检查端点
Akka.Management 为负载均衡器和编排器提供健康检查端点:
| 端点 | 用途 | 返回 200 的条件 |
|---|---|---|
/alive | 存活检查 | ActorSystem 正在运行 |
/ready | 就绪检查 | 集群成员状态为 Up |
/cluster/members | 调试 | 返回集群成员信息 |
ASP.NET Core 健康检查集成
// Register Akka health checks
builder.Services.AddHealthChecks();
// In Akka configuration
builder
.WithActorSystemLivenessCheck() // Adds "akka-liveness" health check
.WithAkkaClusterReadinessCheck(); // Adds "akka-cluster-readiness" health check
// Map endpoints
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("liveness")
});
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("readiness")
});
故障排除
集群无法组建
症状: 节点各自停留在独立的单节点集群中。
检查清单:
- 所有节点使用相同的
ServiceName RequiredContactPointsNr与实际副本数相符- 发现提供程序配置正确
- 网络允许管理端口(8558)上的流量
- 对于 Kubernetes:已设置 RBAC 权限
脑裂
症状: 组建了多个集群,而不是一个集群。
解决方案:
- 设置
ContactWithAllContactPoints = true - 在较慢的环境中增大
StableMargin - 对于 Aspire:设置
FilterOnFallbackPort = false(动态端口) - 对于 Kubernetes:设置
FilterOnFallbackPort = true(固定端口)
Azure 发现问题
症状: 节点无法通过 Azure Tables 找到彼此。
检查清单:
- 连接字符串有效
- 存储帐户允许表操作
- 所有节点使用相同的
ServiceName - 防火墙允许访问 Azure Storage
Aspire 集成
有关 Aspire 特定模式的详细信息,请参阅 akka-net-aspire-configuration 技能。
Aspire 速查:
// In AppHost
appBuilder
.WithEndpoint(name: "remote", protocol: ProtocolType.Tcp,
env: "AkkaSettings__RemoteOptions__Port")
.WithEndpoint(name: "management", protocol: ProtocolType.Tcp,
env: "AkkaSettings__AkkaManagementOptions__Port")
.WithEnvironment("AkkaSettings__ClusterBootstrapOptions__Enabled", "true")
.WithEnvironment("AkkaSettings__ClusterBootstrapOptions__DiscoveryMethod", "AzureTableStorage")
.WithEnvironment("AkkaSettings__ClusterBootstrapOptions__FilterOnFallbackPort", "false");
总结:何时使用哪种方式
| 场景 | 发现方式 | FilterOnFallbackPort |
|---|---|---|
| 本地开发(单节点) | 无(使用种子节点) | 不适用 |
| Aspire 多节点 | AzureTableStorage | false |
| Kubernetes | Kubernetes | true |
| Azure VM/VMSS | AzureTableStorage | true |
| 固定基础设施 | Config | true |
| AWS ECS/EC2 | AWS 发现插件 | true |
评论
支持 Markdown