6

从 Akka actor 内部,如何找出集群的节点?即本地节点认为当前可访问的节点。

谢谢, - 丹尼尔

4

3 回答 3

18

您实际上不需要订阅ClusterDomainEventor MemberEvent。您可以只访问state集群扩展的成员,例如,

val cluster = akka.cluster.Cluster(context.system)

val members = cluster.state.members.filter(_.status == MemberStatus.Up)
于 2014-09-19T22:39:39.383 回答
10

来自Typesafe Activator 教程的调整示例:

case object GetNodes

class MemberListener extends Actor {

  val cluster = Cluster(context.system)

  override def preStart(): Unit =
    cluster.subscribe(self, classOf[MemberEvent])

  override def postStop(): Unit =
    cluster unsubscribe self

  var nodes = Set.empty[Address]

  def receive = {
    case state: CurrentClusterState =>
      nodes = state.members.collect {
        case m if m.status == MemberStatus.Up => m.address
      }
    case MemberUp(member) =>
      nodes += member.address
    case MemberRemoved(member, _) =>
      nodes -= member.address
    case _: MemberEvent ⇒ // ignore
    case GetNodes =>
      sender ! nodes
  }
}
于 2013-07-29T09:04:26.053 回答
4

一种方法可能是让另一个参与者订阅消息,特别是通过事件ClusterDomainEvent查找成员。CurrentClusterState这可能看起来像这样:

case object GetMembers

class ClusterMembersHolder extends Actor{
  var members:Set[Member] = Set()
  override def preStart = {
    val clusterSys = Cluster(context.system)
    clusterSys.subscribe(self, classOf[ClusterDomainEvent])
    clusterSys.publishCurrentClusterState //Forces the current state
  }

  def receive = {
    case state: CurrentClusterState =>
      members = state.members

    case GetMembers => 
      sender ! members
  }
}

这是一个粗略的大纲(可能需要一些调整),但是从这里开始,任何想知道当前成员列表的参与者都可以通过向该参与者发送 GetMembers 消息?并等待响应。

现在这种方法假设您可能有许多需要此信息的演员。如果事实证明您只有一个参与者需要此信息,那么只需让该参与者订阅该事件并使用成员更新其内部状态。

于 2013-07-28T20:35:59.457 回答