如何防止/限制未经授权的节点加入Akka群集?

时间:2020-07-28 12:53:02

标签: scala akka cluster-computing distributed-computing akka-cluster

在Akka群集示例,文档和教程中,似乎只有知道群集和群集的种子节点,任何节点都可以加入群集。如何防止未授权的节点加入?

1 个答案:

答案 0 :(得分:1)

我试图实现此功能,但在Akka群集中也未找到此功能。我设法通过在角色上创建授权标志,将集群包装在Option[Cluster]中,并决定在preStart()方法中对集群上的角色进行订阅或不订阅。这已经阻止了参与者接收消息。但是,它仍然可以向集群成员发送消息。然后,将标志放在case UserMessage(content) if (authorized) => ???上。我没有把演员踢出集群,但我相信这只是他踢完之后的踢腿。

object Alice extends ChatApp("Alice", 2551, true)
object Bob extends ChatApp("Bob", 2552, true)
object Fabio extends ChatApp("Fabio", 2554, false)

演员

class ChatActor(nickname: String, port: Int, authorized: Boolean) extends Actor with ActorLogging {
  // 1: initialize the cluster object
  val cluster: Option[Cluster] = if (authorized) Some(Cluster(context.system)) else None

  // 2: subscribe to cluster event in preStart
  override def preStart(): Unit = {
    if (authorized) {
      cluster match {
        case Some(c) => c.subscribe(
          self,
          initialStateMode = InitialStateAsEvents,
          classOf[MemberEvent]
        )
        case None => log.info(s"user [$nickname] is not authorized to enter in the cluster =(. Please leave the cluster.")
      }
    }
  }

  // 3: unsubscribe self in postStop
  override def postStop(): Unit = {
    cluster match {
      case Some(c) => c.unsubscribe(self)
      case None => log.info(s"user [$nickname] is not authorized to enter in the cluster =(.")
    }
  }

  override def receive: Receive = online(Map())

  /** chatRoom is the data structure to the users in the chat */
  def online(chatRoom: Map[String, String]): Receive = {
    case UserMessage(content) if (authorized) =>
      chatRoom.keys.foreach { address =>
        val chatActorSelection: ActorSelection = context.actorSelection(s"${address}/user/chatActor")
        chatActorSelection ! ChatMessage(nickname, content)
      }
  }
}
相关问题