akka-net-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAkka.NET Management and Service Discovery
Akka.NET Management 与服务发现
When to Use This Skill
何时使用该技能
Use this skill when:
- Deploying Akka.NET clusters to Kubernetes or cloud environments
- Replacing static seed nodes with dynamic service discovery
- Configuring cluster bootstrap for auto-formation
- Setting up health endpoints for load balancers
- Integrating with Azure Table Storage, Kubernetes API, or config-based discovery
在以下场景使用该技能:
- 将Akka.NET集群部署到Kubernetes或云环境中
- 用动态服务发现替代静态种子节点
- 配置集群引导以实现自动构建
- 为负载均衡器设置健康检查端点
- 与Azure Table Storage、Kubernetes API或基于配置的发现机制集成
Reference Files
参考文件
- discovery-providers.md: Config, Kubernetes, and Azure discovery setup with full code and deployment YAML
- configuration-reference.md: Strongly-typed configuration model classes
- discovery-providers.md:包含配置、Kubernetes和Azure发现机制的完整设置代码及部署YAML文件
- configuration-reference.md:强类型配置模型类参考
Overview
概述
Akka.Management provides HTTP endpoints for cluster management and integrates with Akka.Cluster.Bootstrap to enable dynamic cluster formation using service discovery instead of static seed nodes.
Akka.Management 提供用于集群管理的HTTP端点,并与 Akka.Cluster.Bootstrap 集成,支持通过服务发现而非静态种子节点实现动态集群构建。
Why Use Akka.Management?
为何选择Akka.Management?
| Approach | Pros | Cons |
|---|---|---|
| Static Seed Nodes | Simple, no dependencies | Doesn't scale, requires known IPs |
| Akka.Management | Dynamic discovery, scales to N nodes | More configuration, external dependencies |
Use static seed nodes for: Development, single-node deployments, fixed infrastructure.
Use Akka.Management for: Kubernetes, auto-scaling groups, dynamic environments, production clusters.
| 实现方式 | 优点 | 缺点 |
|---|---|---|
| 静态种子节点 | 简单,无依赖 | 无法扩展,需要已知IP地址 |
| Akka.Management | 动态发现,可扩展至N个节点 | 配置更复杂,存在外部依赖 |
使用静态种子节点的场景:开发环境、单节点部署、固定基础设施。
使用Akka.Management的场景:Kubernetes、自动缩放组、动态环境、生产集群。
Architecture
架构
┌─────────────────────────────────────────────────────────────┐
│ 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) │
└───────────┘ └────────────┘ └────────────┘┌─────────────────────────────────────────────────────────────┐
│ 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) │
└───────────┘ └────────────┘ └────────────┘Required NuGet Packages
所需NuGet包
xml
<ItemGroup>
<!-- Core management -->
<PackageReference Include="Akka.Management" />
<PackageReference Include="Akka.Management.Cluster.Bootstrap" />
<!-- Choose ONE discovery provider -->
<PackageReference Include="Akka.Discovery.KubernetesApi" /> <!-- For Kubernetes -->
<PackageReference Include="Akka.Discovery.Azure" /> <!-- For Azure -->
<PackageReference Include="Akka.Discovery.Config.Hosting" /> <!-- For static config -->
</ItemGroup>xml
<ItemGroup>
<!-- 核心管理包 -->
<PackageReference Include="Akka.Management" />
<PackageReference Include="Akka.Management.Cluster.Bootstrap" />
<!-- 选择一个发现提供程序 -->
<PackageReference Include="Akka.Discovery.KubernetesApi" /> <!-- 适用于Kubernetes -->
<PackageReference Include="Akka.Discovery.Azure" /> <!-- 适用于Azure -->
<PackageReference Include="Akka.Discovery.Config.Hosting" /> <!-- 适用于静态配置 -->
</ItemGroup>Akka.Hosting Configuration
Akka.Hosting 配置
Basic Setup with Mode Selection
包含模式选择的基础设置
csharp
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);
}
}csharp
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 Configuration
Akka.Management 配置
csharp
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);
}See discovery-providers.md for complete Config, Kubernetes, and Azure discovery setup code.
See configuration-reference.md for the full strongly-typed configuration model classes.
csharp
private static void ConfigureAkkaManagement(
AkkaConfigurationBuilder builder,
AkkaSettings settings,
IConfiguration configuration)
{
var mgmtOptions = settings.AkkaManagementOptions;
var bootstrapOptions = settings.ClusterBootstrapOptions;
// 重要:使用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;
});
// 配置发现提供程序
ConfigureDiscovery(builder, settings, configuration);
}完整的配置、Kubernetes和Azure发现设置代码,请查看 discovery-providers.md。
完整的强类型配置模型类,请查看 configuration-reference.md。
Health Endpoints
健康检查端点
Akka.Management exposes health endpoints for load balancers and orchestrators:
| Endpoint | Purpose | Returns 200 When |
|---|---|---|
| Liveness | ActorSystem is running |
| Readiness | Cluster member is Up |
| Debug | Returns cluster membership |
Akka.Management 为负载均衡器和编排器暴露以下健康检查端点:
| 端点 | 用途 | 返回200状态码的条件 |
|---|---|---|
| 存活状态检查 | ActorSystem 正在运行 |
| 就绪状态检查 | 集群成员处于Up状态 |
| 调试用 | 返回集群成员信息 |
ASP.NET Core Health Check Integration
ASP.NET Core 健康检查集成
csharp
// 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")
});csharp
// 注册Akka健康检查
builder.Services.AddHealthChecks();
// 在Akka配置中
builder
.WithActorSystemLivenessCheck() // 添加"akka-liveness"健康检查
.WithAkkaClusterReadinessCheck(); // 添加"akka-cluster-readiness"健康检查
// 映射端点
app.MapHealthChecks("/health/live", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("liveness")
});
app.MapHealthChecks("/health/ready", new HealthCheckOptions
{
Predicate = check => check.Tags.Contains("readiness")
});Troubleshooting
故障排查
Cluster Won't Form
集群无法构建
Symptoms: Nodes stay as separate single-node clusters.
Checklist:
- All nodes use same
ServiceName - matches actual replica count
RequiredContactPointsNr - Discovery provider is configured correctly
- Network allows traffic on management port (8558)
- For Kubernetes: RBAC permissions are set
症状: 节点各自保持为独立的单节点集群。
检查清单:
- 所有节点使用相同的
ServiceName - 与实际副本数量匹配
RequiredContactPointsNr - 发现提供程序配置正确
- 网络允许管理端口(8558)的流量
- 对于Kubernetes:已设置RBAC权限
Split Brain
脑裂问题
Symptoms: Multiple clusters form instead of one.
Solutions:
- Set
ContactWithAllContactPoints = true - Increase for slower environments
StableMargin - For Aspire: Set (dynamic ports)
FilterOnFallbackPort = false - For Kubernetes: Set (fixed ports)
FilterOnFallbackPort = true
症状: 形成多个独立集群而非一个统一集群。
解决方案:
- 设置
ContactWithAllContactPoints = true - 为慢环境增大值
StableMargin - 对于Aspire:设置(动态端口)
FilterOnFallbackPort = false - 对于Kubernetes:设置(固定端口)
FilterOnFallbackPort = true
Azure Discovery Issues
Azure发现机制问题
Symptoms: Nodes can't find each other via Azure Tables.
Checklist:
- Connection string is valid
- Storage account allows table operations
- All nodes use same
ServiceName - Firewall allows access to Azure Storage
症状: 节点无法通过Azure Tables找到彼此。
检查清单:
- 连接字符串有效
- 存储账户允许表操作
- 所有节点使用相同的
ServiceName - 防火墙允许访问Azure Storage
Aspire Integration
Aspire 集成
For detailed Aspire-specific patterns, see the skill.
akka-net-aspire-configurationQuick reference for Aspire:
csharp
// 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");有关Aspire特定的详细配置模式,请查看技能。
akka-net-aspire-configurationAspire快速参考:
csharp
// 在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");Summary: When to Use What
总结:不同场景的选型
| Scenario | Discovery Method | FilterOnFallbackPort |
|---|---|---|
| Local development (single node) | None (use seed nodes) | N/A |
| Aspire multi-node | AzureTableStorage | |
| Kubernetes | Kubernetes | |
| Azure VMs/VMSS | AzureTableStorage | |
| Fixed infrastructure | Config | |
| AWS ECS/EC2 | AWS discovery plugins | |
| 场景 | 发现机制 | FilterOnFallbackPort |
|---|---|---|
| 本地开发(单节点) | 无(使用种子节点) | 不适用 |
| Aspire多节点 | AzureTableStorage | |
| Kubernetes | Kubernetes | |
| Azure虚拟机/虚拟机规模集 | AzureTableStorage | |
| 固定基础设施 | 配置文件 | |
| AWS ECS/EC2 | AWS发现插件 | |