4

我在接受远程请求并进行处理和发回响应的服务中实现了 Akka.Net 演员系统。系统中的一些参与者的状态会被持久化到数据库中。当演员系统启动时,这些演员通过从数据库中读取他们的状态来补充水分。

当请求进入时,actor 会按需延迟加载并驻留在内存中以处理进一步的请求。

我现在正在研究如何以最简单的方式提供冗余。

我猜这里最简单的解决方案是在“冷”待机状态下拥有第二份服务副本。当第一个节点出现故障时,请求被路由到第二个节点 - 然后它将开始创建参与者并从数据库中获取它们的状态。

然后,当原始节点出现时,需要识别它不是“主要”节点并终止所有参与者(因此当它变为活动时,它可以从磁盘读取它们的状态)

实现这一目标的最佳方式是什么?我猜我应该使用 Akka.Cluster 并监听节点何时加入或离开集群?但是我怎么说所有的消息本质上都应该发送到一个节点呢?是否存在某种领导者选举过程,但针对单个角色而不是整个集群?

有没有更好/更简单的方法来做到这一点?

4

1 回答 1

0

我是使用 akka.net 的新手,但我认为您可以使用 Akka.Net Cluster + SingletonActor。我在这里进行了一些测试,它似乎工作得很好。

样本:

    private void Start() {
        var system = ActorSystem.Create("SingletonActorSystem");
        var cluster = Cluster.Get(system);
        cluster.RegisterOnMemberRemoved(() => MemberRemoved(system));

        var actor = system.ActorOf(ClusterSingletonManager.Props(
            singletonProps: Props.Create<ProcessorCoordinatorActor>(),
            terminationMessage: PoisonPill.Instance,
            settings: ClusterSingletonManagerSettings.Create(system)),
            name: "processorCoordinator");

        Console.ReadLine();

        cluster.Leave(cluster.SelfAddress);
        _leaveClusterEvent.WaitOne();
    }

    private async void MemberRemoved(ActorSystem actorSystem) {
        await actorSystem.Terminate();
        _leaveClusterEvent.Set();
    }

配置:

    akka {
        suppress-json-serializer-warning = on

        actor {
            provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
        }

        remote {
            helios.tcp {
                port = 0
                hostname = localhost
            }
        }

        cluster {
            auto-down-unreachable-after = 5s
            down-removal-margin = 5s
            seed-nodes = [ "akka.tcp://SingletonActorSystem@127.0.0.1:4053" ] 
            roles = [worker]

            singleton {
                singleton-name = "processorCoordinator"
                role = "worker"
                hand-over-retry-interval = 5s
            }
        }
    }
于 2016-08-08T02:12:32.680 回答