Обработка избыточности и отказоустойчивости в Akka.Net

Я реализовал акторную систему Akka.Net в службе, которая принимает удаленные запросы, выполняет обработку и отправляет ответы. Состояние некоторых участников системы сохраняется в базе данных. Когда система акторов запускается, эти акторы увлажняются, считывая свое состояние из базы данных.

Когда приходит запрос, акторы лениво загружаются по запросу и остаются в памяти для обработки дальнейших запросов.

Сейчас я ищу, как я могу обеспечить избыточность самым простым способом.

Я предполагаю, что самое простое решение здесь — иметь вторую копию службы в «холодном» резерве. Когда первый узел выходит из строя, запросы перенаправляются на второй узел, который затем начинает создавать акторов и получать их состояние из базы данных.

Затем исходный узел, когда он появится, должен распознать, что он не является «основным», и завершить работу всех акторов (чтобы он мог прочитать их обратно с их состоянием с диска, когда он станет активным).

Что лучше всего для этого? Я предполагаю, что мне следует использовать Akka.Cluster и слушать, когда узлы присоединяются к кластеру или покидают его? Но как я могу сказать, что все сообщения должны по существу отправляться на один узел? Существует ли какой-то процесс выбора лидера, но для отдельных ролей, а не для кластера в целом?

Есть ли лучший/более простой способ сделать это?


person statictype    schedule 23.03.2016    source источник


Ответы (1)


Я новичок в использовании 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://[email protected]:4053" ] 
            roles = [worker]

            singleton {
                singleton-name = "processorCoordinator"
                role = "worker"
                hand-over-retry-interval = 5s
            }
        }
    }
person Oberdan Nunes    schedule 08.08.2016