Как решить: Akka.Remote.EndpointDisassociatedException?

У меня есть некоторый код, который включает удаленное развертывание субъектов в отдельном процессе.

Я получаю: Akka.Remote.EndpointDisassociatedException

[ПРЕДУПРЕЖДЕНИЕ][24.03.2017 13:54:32][Thread 0008][[akka://system1/system/endpointManager/reliableEndpointWriter-akka.tcp%3A%2F%2Fsystem2%40localhost%3A8080-1 #1408457 663]] Ошибка ассоциации с удаленной системой akka.tcp://system2@localhost:8080; адрес теперь закрыт на 5000 мс. Причина: [Akka.Remote.EndpointDisassociatedException: Disassociated at Akka.Remote.EndpointWriter.PublishAndThrow (причина исключения, уровень LogLevel l, логическое значение needToThrow) в Akka.Actor.ReceiveActor.ExecutePartialMessageHandler (сообщение объекта, Parti alAction1 partialAction) at Akka.Actor.ActorCell.<>c__DisplayClass114_0.<Akka.Actor.IUntypedActorConte xt.Become>b__0(Object m) at Akka.Actor.ActorBase.AroundReceive(Receive receive, Object message)
at Akka.Actor.ActorCell.ReceiveMessage(Object message) at Akka.Actor.ActorCell.AutoReceiveMessage(Envelope envelope) at Akka.Actor.ActorCell.Invoke(Envelope envelope)] [ERROR][3/24/2017 1:54:32 PM][Thread 0008][akka://system1/system/endpointManager /reliableEndpointWriter-akka.tcp%3A%2F%2Fsystem2%40localhost%3A8080-1/endpointWr iter] Disassociated Cause: Akka.Remote.EndpointDisassociatedException: Disassociated at Akka.Remote.EndpointWriter.PublishAndThrow(Exception reason, LogLevel leve l, Boolean needToThrow) at Akka.Actor.ReceiveActor.ExecutePartialMessageHandler(Object message, Parti alAction
1 partialAction) в Akka. Actor.ActorCell.‹>c__DisplayClass114_0.b__0(объект m) в Akka.Actor.ActorBase.AroundReceive(получение получения, сообщение объекта)
в Akka.Actor.ActorCell.ReceiveMessage(сообщение объекта) в Akka.Actor.ActorCell. AutoReceiveMessage (конверт конверта) в Akka.Actor.ActorCell.Invoke (конверт конверта)

Вот код, который я выполняю в отдельном процессе, который вызывает эту ошибку:

use system = ActorSystem.Create("system1", config)
let reply = system.ActorOf<ReplyActor>("reply")

let props1 = Props.Create(typeof<SomeActor>, [||])
let props2 = Props.Create(typeof<SomeActor>, [||])
let props3 = Props.Create(typeof<SomeActor>, [||])

let remote1 = system.ActorOf(props1.WithRouter(FromConfig.Instance), "remoteactor1")
let remote2 = system.ActorOf(props2.WithRouter(FromConfig.Instance), "remoteactor2")
let remote3 = system.ActorOf(props3.WithRouter(FromConfig.Instance), "remoteactor3")

let hashGroup = system.ActorOf(Props.Empty.WithRouter(ConsistentHashingGroup(config)))
Task.Delay(500).Wait();

let routee1 = Routee.FromActorRef(remote1);
hashGroup.Tell(new AddRoutee(routee1));

let routee2 = Routee.FromActorRef(remote2);
hashGroup.Tell(new AddRoutee(routee2));

let routee3 = Routee.FromActorRef(remote3);
hashGroup.Tell(new AddRoutee(routee3));

Task.Delay(500).Wait();

for i = 0 to 5 do
    for j = 0 to 7 do

        let message = new HashMessage(j, sprintf "remote message: %i" j);
        hashGroup.Tell(message, reply);

Console.ReadLine() |> ignore

Вот конфигурация, на которую опирается мой код удаленного развертывания:

open Akka.Configuration

let config = ConfigurationFactory.ParseString(@"
    akka {  
        log-config-on-start = on
        stdout-loglevel = DEBUG
        loglevel = DEBUG
        actor {
            provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""

            debug {  
              receive = on 
              autoreceive = on
              lifecycle = on
              event-stream = on
              unhandled = on
            }

            deployment {
                /localactor {
                    router = consistent-hashing-pool
                    nr-of-instances = 5
                    virtual-nodes-factor = 10
                }
                /remoteactor1 {
                    router = consistent-hashing-pool
                    nr-of-instances = 5
                    remote = ""akka.tcp://system2@localhost:8080""
                }
                /remoteactor2 {
                    router = consistent-hashing-pool
                    nr-of-instances = 5
                    remote = ""akka.tcp://system2@localhost:8080""
                }
                /remoteactor3 {
                    router = consistent-hashing-pool
                    nr-of-instances = 5
                    remote = ""akka.tcp://system2@localhost:8080""
                }
            }
        }
        remote {
            helios.tcp {
                port = 8090
                hostname = localhost
            }
        }
    }
    ")

Вот действительно работающий код C#, на котором основана моя реализация F#:

var config = ConfigurationFactory.ParseString(@"
akka {  
    log-config-on-start = on
    stdout-loglevel = DEBUG
    loglevel = DEBUG
    actor {
        provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""

        debug {  
          receive = on 
          autoreceive = on
          lifecycle = on
          event-stream = on
          unhandled = on
        }

        deployment {
            /localactor {
                router = consistent-hashing-pool
                nr-of-instances = 5
                virtual-nodes-factor = 10
            }
            /remoteactor1 {
                router = consistent-hashing-pool
                nr-of-instances = 5
                remote = ""akka.tcp://system2@localhost:8080""
            }
            /remoteactor2 {
                router = consistent-hashing-pool
                nr-of-instances = 5
                remote = ""akka.tcp://system2@localhost:8080""
            }
            /remoteactor3 {
                router = consistent-hashing-pool
                nr-of-instances = 5
                remote = ""akka.tcp://system2@localhost:8080""
            }
        }
    }
    remote {
        dot-netty.tcp {
            port = 8090
            hostname = localhost
        }
    }
}
");
            using (var system = ActorSystem.Create("system1", config))
            {
                var reply = system.ActorOf<ReplyActor>("reply");

                //create a remote deployed actor
                var remote1 = system.ActorOf(Props.Create(() => new SomeActor(null, 123)).WithRouter(FromConfig.Instance), "remoteactor1");
                var remote2 = system.ActorOf(Props.Create(() => new SomeActor(null, 456)).WithRouter(FromConfig.Instance), "remoteactor2");
                var remote3 = system.ActorOf(Props.Create(() => new SomeActor(null, 789)).WithRouter(FromConfig.Instance), "remoteactor3");

                var hashGroup = system.ActorOf(Props.Empty.WithRouter(new ConsistentHashingGroup(config)));

                Task.Delay(500).Wait();

                var routee1 = Routee.FromActorRef(remote1);
                hashGroup.Tell(new AddRoutee(routee1));

                var routee2 = Routee.FromActorRef(remote2);
                hashGroup.Tell(new AddRoutee(routee2));

                var routee3 = Routee.FromActorRef(remote3);
                hashGroup.Tell(new AddRoutee(routee3));

                Task.Delay(500).Wait();

                for (var i = 0; i < 5; i++)
                {
                    for (var j = 0; j < 7; j++)
                    {
                        var message = new SomeMessage(j, $"remote message: {j}");
                        hashGroup.Tell(message, reply);
                    }
                }

                Console.ReadLine();
            }
        }
    }
}

Кто-нибудь может подсказать, почему я получаю это исключение и как его устранить?

Таким образом, реализация F# точно отражает рабочую реализацию C#. код F# можно найти на GitHub.


person Scott Nimrod    schedule 24.03.2017    source источник


Ответы (1)


Когда вы запускаете свое приложение, вы можете прочитать точное исключение, которое вызывает отсоединение узла: Could not load file or assembly 'System1....

То, что вы определили в конфигурации маршрутизаторов, — это удаленное развертывание. Это означает, что из одной системы вы пытаетесь создать акторов на другом узле и общаться с ними, как если бы они были доступны локально. Хотя это возможно, есть одно требование: целевая система субъектов должна знать, как создать субъект. Поскольку ваши акторы определены в System1 и созданы в System2, которая ничего не знает о SomeActor, происходит сбой, и система акторов разрывается.

Вам нужно передать класс SomeActor в общую сборку, доступную для обеих систем, чтобы ваш сценарий работал.

person Bartosz Sypytkowski    schedule 24.03.2017