什么是Akka集群Singleton启动的正确方法

时间:2017-03-21 08:06:30

标签: singleton akka akka-cluster

我尝试为akka集群启动实现方案:

  1. 使用简单的actor(集群监视器,显示其他成员的连接)运行集群种子
  2. 运行一些群集成员,该成员使用ClusterSingletonManagerClusterSingletonProxy个参与者进行Singleton实施
  3. 但我有一个问题:

    10:52:41.691UTC INFO  akka.tcp://system@127.0.0.1:9401/user/singletonOfEvents - ClusterSingletonManager state change [Start -> Younger]
    

    我的单身人士没有开始。

    我看到"单身演员总是在具有指定角色的最老的成员上运行。"在Akka Cluster Singleton doc。但我无法理解必须如何启动单身人士。也许所有单例都必须在第一个种子节点中实现并启动?

1 个答案:

答案 0 :(得分:1)

如Akka文档中所述,Cluster Singleton actor实例由具有指定单例角色的每个集群节点上的ClusterSingletonManager actor启动和维护。 ClusterSingletonManager在群集的最旧节点上最多维护一个单一实例,并在任何时间点具有指定的角色。如果最旧的节点(可能是第一个种子节点)发生故障,则将选择下一个最旧的节点。要访问集群单例actor,请使用具有指定角色的所有节点上的ClusterSingletonProxy。

以下是启动Cluster Singleton的示例应用程序可能如下所示:

object Main {

  def workTimeout = 10.seconds

  def main(args: Array[String]): Unit = {
    // Validate arguments host and port from args(0) and args(1)
    // ...

    val role = "worker"

    val conf = ConfigFactory.parseString(s"akka.cluster.roles=[$role]").
      withFallback(ConfigFactory.parseString("akka.remote.netty.tcp.hostname=" + host)).
      withFallback(ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port)).
      withFallback(ConfigFactory.load())

    val system = ActorSystem("ClusterSystem", conf)

    system.actorOf(
      ClusterSingletonManager.props(
        Master.props(workTimeout),
        PoisonPill,
        ClusterSingletonManagerSettings(system).withRole(role)
      ),
      name = "master"
    )

    val singletonAgent = system.actorOf(
      ClusterSingletonProxy.props(
        singletonManagerPath = "/user/master",
        settings = ClusterSingletonProxySettings(system).withRole(role)
      ),
      name = "proxy"
    )

    // ...
  }

  // ...
}

object Master {
  def props(workTimeout: FiniteDuration): Props =
    Props(classOf[Master], workTimeout)

  // ...
}

class Master(workTimeout: FiniteDuration) extends Actor  {
  import Master._

  // ...
}

群集配置可能如下所示:

akka {

  actor.provider = "akka.cluster.ClusterActorRefProvider"

  remote.netty.tcp.port = 0
  remote.netty.tcp.hostname = 127.0.0.1

  cluster {
    seed-nodes = [
      "akka.tcp://ClusterSystem@10.1.1.1:2552",
      "akka.tcp://ClusterSystem@10.1.1.2:2552"
    ]

    auto-down-unreachable-after = 10s
  }

  // ...
}