2016-03-23 24 views
3

Ich habe ein Akka.Net Actor-System in einem Dienst implementiert, der Remote-Anforderungen akzeptiert und verarbeitet und Antworten zurücksendet. Einige der Akteure im System haben einen Status, der in einer Datenbank gespeichert wird. Wenn das Aktorsystem gestartet wird, werden diese Akteure durch Lesen ihres Zustands aus der Datenbank hydriert.Umgang mit Redundanz und Failover in Akka.Net

Wenn eine Anfrage eingeht, werden die Actors bei Bedarf faul geladen und verbleiben im Speicher, um weitere Anfragen zu bearbeiten.

Ich schaue mir jetzt an, wie ich auf die einfachste Weise Redundanz bereitstellen kann.

Ich schätze die einfachste Lösung hier ist, eine zweite Kopie des Dienstes auf "kalten" Standby zu haben. Wenn der erste Knoten ausfällt, werden Anfragen an den zweiten Knoten weitergeleitet, der dann beginnt, Akteure zu erstellen und ihren Status von der Datenbank abzurufen.

Dann wird der ursprüngliche Knoten, wenn er kommt, muss erkennen, dass es nicht die ‚primäre‘ und alle Akteure beenden (so kann sie wieder mit ihrem Zustand von der Festplatte gelesen werden, wenn es aktiv wird)

Was ist das Beste, um das zu erreichen? Ich schätze, ich sollte Akka.Cluster verwenden und darauf achten, wenn Knoten einem Cluster beitreten oder ihn verlassen. Aber wie soll ich sagen, dass alle Nachrichten im Wesentlichen zu einem Knoten gehen sollen? Gibt es eine Art Leader-Wahl-Prozess, sondern für einzelne Rollen anstelle des Clusters als Ganzes?

Gibt es einen besseren/einfacheren Weg, dies zu tun?

Antwort

0

Ich bin ein Neuling mit akka.net, aber ich denke, dass Sie Akka.Net Cluster + SingletonActor verwenden können. Ich mache hier ein paar Tests und es scheint sehr gut zu funktionieren.

Probe:

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(); 
    } 

Konfiguration:

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 
      } 
     } 
    }