如何在运行时定义种子节点

How can I define seed-nodes in runtime

我有一个带有 application.conf 的 akka 集群,如下所示:

 remote { // Remote configuration for this seed node
  enabled-transports = ["akka.remote.netty.tcp"]
  netty.tcp {
    hostname = ""
    port = 2555
  }
}
cluster {
  seed-nodes = [
    "akka.tcp://automation-akka-http@10.0.0.4:2555",
    "akka.tcp://automation-akka-http@10.0.0.5:2555"
  ] // Seed nodes of the cluster
  auto-down-unreachable-after = 10s
}

现在,种子节点是硬编码的。我想在这里配置一个参数:

cluster {
  seed-nodes = [
    "akka.tcp://automation-akka-http@${?HOST1}:2555",
    "akka.tcp://automation-akka-http@${?HOST2}:2555"
  ] // Seed nodes of the cluster
  auto-down-unreachable-after = 10s
}

我知道我可以在 sbt 命令中定义这些参数进行编译。但这并不能解决我的问题,因为我只能在部署阶段获得种子节点的 IP。有没有办法在启动时定义这些参数。

Akka Cluster Documentation

中所述

您可以使用 Cluster(system).joinSeedNodes 以编程方式加入种子节点。

根据Akka API docs,它需要一个 akka.actor.Address 的序列,这将是您的种子节点地址。

所以这样的事情应该有效:

val seeds = Seq(Address("akka.tcp", "RemoteSystem1", "host1", 1234),
                Address("akka.tcp", "RemoteSystem2", "host2", 1234)

Cluster(system).joinSeedNodes(seeds)

哪里根据Address API docs

  • "akka.tcp" = 协议
  • "RemoteSystem1" = 远程参与者系统的名称
  • "host1" = 远程actor系统主机
  • 1234 = 远程参与者系统的端口

编辑

GitHub

上创建了一个最小示例
val cluster = Cluster(context.system)

// Join the seed node with the given address
seedPort match {
  case Some(port) =>
    cluster.joinSeedNodes(immutable.Seq(Address("akka.tcp", "ClusterSystem", "127.0.0.1", port)))
  case _ =>
}

可以 运行 与 sbt "run akkaPort [clusterPort]"。因此,最初使用两个相同的端口启动集群 运行:

sbt "run 1337 1337"

然后 运行 具有不同 akkaPort 的附加节点:

sbt "run 1338 1337"

此节点随后将加入。

如果省略 clusterPort 参数,则不会执行此行:

cluster.joinSeedNodes(immutable.Seq(Address("akka.tcp", "ClusterSystem", "127.0.0.1", port))) 

因此只使用 application.conf 文件中的种子节点。