Akka.net:访问集群中的远程Actor

本文关键字:Actor net 访问 Akka | 更新日期: 2023-09-27 18:36:09

在集群环境中,我有一个种子节点以及节点 1 和节点 2。

从节点 1 我想向在节点 2 上创建的 Actor 发送一条消息。node2 上此节点的本地路径是 akka:MyAkkaSystem/user/AnActor。

现在,我想使用如下所示的 ActorSelect 将消息从节点 1 从 Actor 发送到此特定 actor:

var actorSystem = ActorSystem.Create("MyTestSystem");
var c = actorSystem.ActorSelection("/user/ConsoleReceiver");
c.Tell("Hello World");

在节点 2 上,参与者是这样创建的:

var actorSystem = ActorSystem.Create("MyTestSystem");
            var r = actorSystem.ActorOf(Props.Create<MessageReceiver>(), "ConsoleReceiver");
            Console.WriteLine(r.Path);
            Console.ReadLine();
            actorSystem.Terminate().Wait();

不幸的是,这行不通,因为尝试以死信结束。

节点 2 上的 HOCON 配置如下所示:

akka {
    actor {
      provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"                  
      deployment {                  
      }              
    }
    remote {
      log-remote-lifecycle-events = DEBUG
      log-received-messages = on
      helios.tcp {
        transport-class = "Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"
            applied-adapters = []
            transport-protocol = tcp       
        hostname = "127.0.0.1"
        port = 0
      }
    }            
    cluster {
      #will inject this node as a self-seed node at run-time
      seed-nodes = ["akka.tcp://webcrawler@127.0.0.1:4053"] #manually populate other seed nodes here, i.e. "akka.tcp://lighthouse@127.0.0.1:4053", "akka.tcp://lighthouse@127.0.0.1:4044"
      roles = [crawler]
    }
  }

作为种子节点,我正在使用灯塔。从连接的角度来看,一切似乎都解决了。已找到种子,并且每个节点都收到了欢迎消息。

我以为我在集群上具有位置透明度,并且可以像本地资源一样访问远程资源。

Akka.net:访问集群中的远程Actor

我以为我在集群上具有位置透明度,并且可以像本地资源一样访问远程资源。

这并不容易。请考虑以下方案:如果在同一路径下的两个节点上创建了一个Actor,该怎么办。如果您尝试使用相对路径 - 而不显示您想到的节点 - 哪个参与者应该接收消息?

使用基本的群集功能,您可以使用 Context.ActorSelection(_cluster.ReadView.Members.Single(m => /* which node you want to choose */).Address + "/user/ConsoleReceiver"); 轻松选择节点。群集扩展提供读取视图数据,其中包含有关当前节点可见的所有成员的信息。

有许多方法可以将消息发送到另一个参与者,而不必知道它位于哪个节点上。

第一种方法是使用群集单例功能Akka.Cluster.Tools它允许您创建群集中存在的参与者的最多一个实例。如果节点发生故障,它将迁移到另一个节点。请注意,如果您希望让许多参与者以这种方式工作,则不应使用此解决方案。它更适合不同的特殊情况演员。

第二种方法是使用分布式发布/订阅功能Akka.Cluster.Tools在订阅特定主题的群集中的参与者之间广播群集范围的事件,而无需担心其实际位置。这是消息广播方案的不错选择。

最后一种方法是使用 Akka.Cluster.Sharding 功能,该功能可自动管理参与者生命周期 - 您不需要显式创建参与者 - 它还能够从集群中的任何位置将消息路由到它们,并可以在需要时跨多个群集节点重新平衡它们。