Akka Cluster Client是否可以向不在初始联系人中的群集节点发送消息?

时间:2016-03-04 00:21:49

标签: akka akka-cluster typesafe

使用Akka 2.3.14,我试图创建各种服务的Akka集群。到现在为止,我已经拥有了所有的服务和#34;在一个集群在多个节点上的工件中,但现在我试图将这个工件分解为同一集群中存在的多个服务。

因此,为了解决这个问题,我们设计了它,以便群集上的任何节点首先尝试连接到种子节点。如果没有种子节点,它将查看它是否是作为种子节点运行的候选者(如果它在种子节点可以在同一主机上),在这种情况下它将获取打开种子节点端口并成为种子节点。因此,从这个意义上说,集群中的任何服务都可以成为种子节点。

至少,这就是主意。我们作为单独服务运行的此系统的API将ClusterClient实现到此系统中。 initialContacts设置为与种子节点相同。问题是我可以通过ClusterClient发送消息的唯一接待员是种子节点上的actor。

如果有帮助,这是一个例子。假设我有一个String Service和一个Double Service,每个服务的接待员分别是StringActor和DoubleActor。现在假设我有一个客户端服务,它将StringMessages和DoubleMessages发送到StringActor和DoubleActor

为简单起见,我们假设我有两个节点,server1和server2,然后:

seed-nodes = ["akka.tcp://system@server1:2773", "akka.tcp://system@server2:2773"]

我的ClusterClient会像这样初始化:

system.actorOf(
    ClusterClient.props(
        Set(
            system.actorSelection("akka.tcp://system@server1:2773/user/receptionist"),
            system.actorSelection("akka.tcp://system@server2:2773/user/receptionist")
        )
    ),     
    "clusterClient"
)

以下是我发生的情景:

  1. 如果StringServices首先在两个服务器上启动,那么来自客户端服务的DoubleMessages就会消失在以太网中。
  2. 如果DoubleServices首先在两台服务器上启动,那么来自客户端服务的StringMessages就会消失在以太网中。
  3. 如果StringService首先在serverX上启动并且DoubleService首先在serverY上启动,那么所有StringMessages都将被发送到serverX,所有DoubleMessages将被发送到serverY,这不像上面那样糟糕,但它意味着它并没有真正扩展。
  4. 这不是我的预期,它可能只是我代码中的一个缺陷,所以我想知道这是否是预期的行为。如果没有,那么还有另一个Akka概念可以帮助我吗?

    可以说,我可以只使一个服务类型成为我的入口点,就像可以接受StringMessages或DoubleMessages的RoutingService,然后将其发送到正确的服务。但是,如果客户端服务只能向初始联系人中的RoutingService实例发送消息,那么我无法动态扩展RoutingService,因为无论我添加多少个节点,客户端服务都只能发送给初始联系人。

    我还考虑在我的客户端服务中订阅ClusterEvents,看看我是否可以在群集中启动节点时添加和删除群集客户端中的初始联系人,但我不确定是否这是可能的,感觉应该有更好的解决方案。

1 个答案:

答案 0 :(得分:4)

这是我在进行更多故障排除时发现的,以防它帮助其他任何人:

ClusterClient将尝试按顺序连接到初始联系人,然后仅通过该连接发送消息。如果要在每个节点上部署不同的服务,则会遇到问题,因为从ClusterClient发送的消息将仅发送到与其建立连接的节点。通过这种方式,您可以将ClusterClient视为合法客户端,它将连接到您提供的URL,然后通过该URL继续与服务器通信。

阅读Distributed Workers示例,我意识到我的前端,或者在本例中是我的路由服务,实际上应该是群集的一部分,而不是充当客户端。为此,我使用了DistributedPubSub方法。