Akka: How to find the current nodes in a cluster?

2019-02-05 05:24发布

From within an Akka actor, how can you find out the nodes of the cluster? That is, the nodes which the local node considers to be currently accessible.

Thanks, - Daniel

3条回答
闹够了就滚
2楼-- · 2019-02-05 06:04

Tweaked sample from Typesafe Activator tutorial:

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
  }
}
查看更多
forever°为你锁心
3楼-- · 2019-02-05 06:17

You actually do not need to subscribe to ClusterDomainEvent or MemberEvent. You can just access the state member of the Cluster extension, e.g.,

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

val members = cluster.state.members.filter(_.status == MemberStatus.Up)
查看更多
我想做一个坏孩纸
4楼-- · 2019-02-05 06:20

One approach could be to have another actor subscribe into ClusterDomainEvent messages, specifically looking for the members via the CurrentClusterState event. That might look something like this:

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
  }
}

This is kind of a rough outline (might need a few tweaks), but from here, any actor that wanted to know the current members list could send a GetMembers message to this actor via ? and wait for the response.

Now this approach assumes that you might have many actors who want this info. If it turns out that you only had one actor that wants this info then just have that actor subscribe into that event and update its internal state with the members.

查看更多
登录 后发表回答