akka-net-management

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Akka.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?

ApproachProsCons
Static Seed NodesSimple, no dependenciesDoesn't scale, requires known IPs
Akka.ManagementDynamic discovery, scales to N nodesMore 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:
EndpointPurposeReturns 200 When
/alive
LivenessActorSystem is running
/ready
ReadinessCluster member is Up
/cluster/members
DebugReturns cluster membership
Akka.Management 为负载均衡器和编排器暴露以下健康检查端点:
端点用途返回200状态码的条件
/alive
存活状态检查ActorSystem 正在运行
/ready
就绪状态检查集群成员处于Up状态
/cluster/members
调试用返回集群成员信息

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:
  1. All nodes use same
    ServiceName
  2. RequiredContactPointsNr
    matches actual replica count
  3. Discovery provider is configured correctly
  4. Network allows traffic on management port (8558)
  5. For Kubernetes: RBAC permissions are set
症状: 节点各自保持为独立的单节点集群。
检查清单:
  1. 所有节点使用相同的
    ServiceName
  2. RequiredContactPointsNr
    与实际副本数量匹配
  3. 发现提供程序配置正确
  4. 网络允许管理端口(8558)的流量
  5. 对于Kubernetes:已设置RBAC权限

Split Brain

脑裂问题

Symptoms: Multiple clusters form instead of one.
Solutions:
  1. Set
    ContactWithAllContactPoints = true
  2. Increase
    StableMargin
    for slower environments
  3. For Aspire: Set
    FilterOnFallbackPort = false
    (dynamic ports)
  4. For Kubernetes: Set
    FilterOnFallbackPort = true
    (fixed ports)
症状: 形成多个独立集群而非一个统一集群。
解决方案:
  1. 设置
    ContactWithAllContactPoints = true
  2. 为慢环境增大
    StableMargin
  3. 对于Aspire:设置
    FilterOnFallbackPort = false
    (动态端口)
  4. 对于Kubernetes:设置
    FilterOnFallbackPort = true
    (固定端口)

Azure Discovery Issues

Azure发现机制问题

Symptoms: Nodes can't find each other via Azure Tables.
Checklist:
  1. Connection string is valid
  2. Storage account allows table operations
  3. All nodes use same
    ServiceName
  4. Firewall allows access to Azure Storage

症状: 节点无法通过Azure Tables找到彼此。
检查清单:
  1. 连接字符串有效
  2. 存储账户允许表操作
  3. 所有节点使用相同的
    ServiceName
  4. 防火墙允许访问Azure Storage

Aspire Integration

Aspire 集成

For detailed Aspire-specific patterns, see the
akka-net-aspire-configuration
skill.
Quick 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-configuration
技能。
Aspire快速参考:
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

总结:不同场景的选型

ScenarioDiscovery MethodFilterOnFallbackPort
Local development (single node)None (use seed nodes)N/A
Aspire multi-nodeAzureTableStorage
false
KubernetesKubernetes
true
Azure VMs/VMSSAzureTableStorage
true
Fixed infrastructureConfig
true
AWS ECS/EC2AWS discovery plugins
true
场景发现机制FilterOnFallbackPort
本地开发(单节点)无(使用种子节点)不适用
Aspire多节点AzureTableStorage
false
KubernetesKubernetes
true
Azure虚拟机/虚拟机规模集AzureTableStorage
true
固定基础设施配置文件
true
AWS ECS/EC2AWS发现插件
true