Akka集群手动加入

Akka Cluster manual join

我正在尝试找到解决以下限制的方法:从头开始启动 Akka 集群时,必须确保第一个种子节点已启动。这对我来说是个问题,因为如果我遇到紧急情况需要从头重新启动我的所有系统,谁知道一切都依赖的那台机器是否会启动并且 运行 正常?而且我可能没有时间花时间更改系统配置。因此,我尝试手动创建集群,而不依赖于静态种子节点列表。

现在我可以很容易地让所有 Akka 系统在某个地方注册自己(例如,网络文件系统,通过定期访问文件)。因此在启动新系统时可以

  1. 查找所有假定处于活动状态的系统的列表(即最近接触文件系统的人)。
  2. 一个。如果有none,则新系统自己加入,即单独启动集群。 b.否则,它会尝试使用所有其他假定存在的系统作为种子来加入 Cluster(system).joinSeedNodes 的集群。
  3. 如果2.b.在合理的时间内没有成功,新系统从 1 开始再次尝试。最终落入2.a.).

我不确定如何实现3.:如何知道加入是成功还是失败? (需要订阅集群事件?)是否可以在失败的情况下再次调用Cluster(system).joinSeedNodes?官方文档在这一点上不是很明确,我不是 100% 如何在我的案例中解释以下内容(我可以做几次尝试,使用不同的种子吗?):

An actor system can only join a cluster once. Additional attempts will be ignored. When it has successfully joined it must be restarted to be able to join another cluster or to join the same cluster again.

最后,让我明确一点,我正在构建一个小型集群(目前只有 10 个系统,并且不会增长到很大)并且必须时不时地从头开始重新启动(我不能假设集群将永远存在。

感谢

您不需要种子节点。如果您希望集群自动启动,则需要种子节点。

您可以启动您的个人应用程序,然后让它们 "manually" 在任何时间点加入集群。例如,如果你启用了http,你可以使用the akka-management library(或者自己实现它的一个子集,它们都是基本的集群库函数,只是很好地包装)。

我强烈反对触摸方法。你如何同步节点之间的触摸读/写?如果有人读取瞬态(而其他人正在写入)怎么办?

我会说要么完全自动(使用多个种子节点),要么完全 "manual" 并让另一个系统负责管理节点的集群化。我的意思是你单独启动它们,它们只有在外部主管命令时才加入集群(对管理裂脑也很有帮助)。

我们已经开始使用 Constructr 扩展,而不是种子节点的静态列表:

https://github.com/hseeberger/constructr

这没有静态配置的第一个种子节点必须在整个集群重新启动后启动的限制。

相反,它依赖于高度可用的查找服务。 Constructr 原生支持 etcd,并且有(至少)zookeeper 和 consul 的扩展可用。由于我们已经有一个 kafka 的 zookeeper 集群,所以我们选择了 zookeeper:

https://github.com/typesafehub/constructr-zookeeper

我正在回答我自己的问题,让人们知道我最终是如何解决我的问题的。 Michal Borowiecki 的回答提到了 ConstructR 项目,我在他们的代码上构建了我的答案。

如何知道加入成功还是失败?发出Cluster(system).joinSeedNodes后我订阅了集群事件并开始超时:

private case object JoinTimeout
...
Cluster(context.system).subscribe(self, InitialStateAsEvents, classOf[MemberUp], classOf[MemberLeft])
system.scheduler.scheduleOnce(15.seconds, self, JoinTimeout)

receive是:

val address = Cluster(system).selfAddress
...
case MemberUp(member) if member.address == address =>
  // Hooray, I joined the cluster!
case JoinTimeout =>
  // Oops, couldn't join
  system.terminate()

是否可以在失败的情况下再次调用Cluster(system).joinSeedNodes可能,也可能不会。但实际上,如果加入不成功,我只是终止 actor 系统并重新启动它再试一次(所以它是 actor 系统级别的 "let it crash" 模式)。