我如何解决:Akka.Remote.EndpointDisassociatedException?

How do I resolve: Akka.Remote.EndpointDisassociatedException?

some code 涉及将参与者远程部署到单独的进程中。

我得到:Akka.Remote.EndpointDisassociatedException

[WARNING][3/24/2017 1:54:32 PM][Thread 0008][[akka://system1/system/endpointMana ger/reliableEndpointWriter-akka.tcp%3A%2F%2Fsystem2%40localhost%3A8080-1#1408457 663]] Association with remote system akka.tcp://system2@localhost:8080 has faile d; address is now gated for 5000 ms. Reason is: [Akka.Remote.EndpointDisassociat edException: Disassociated at Akka.Remote.EndpointWriter.PublishAndThrow(Exception reason, LogLevel leve l, Boolean needToThrow) at Akka.Actor.ReceiveActor.ExecutePartialMessageHandler(Object message, 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)<br> 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 alAction1 partialAction) at Akka.Actor.ActorCell.<>c__DisplayClass114_0.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)

这是我在触发该错误的单独进程中执行的代码:

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

这是我的 F# 实现基于的实际工作的 C# 代码:

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# code can be found on GitHub.

当您启动应用程序时,您可能会读到导致节点解除关联的确切异常:Could not load file or assembly 'System1...

您在路由器配置中定义的是远程部署。这意味着,您试图从一个系统在另一个节点上创建参与者并与他们通信,就好像他们在本地可用一样。虽然这是可能的,但有一个要求:目标 actor 系统必须知道如何构建 actor。由于您的演员是在 System1 中定义并在 System2 中创建的,它对 SomeActor 一无所知,因此失败并导致演员系统分离。

您需要将 SomeActor class 传递给两个系统都可用的共享程序集,以便您的场景正常工作。