AKKA-如果某个角色的名称在群集中不是唯一的,那么如何阻止它的创建

时间:2017-01-03 16:09:15

标签: scala akka akka-cluster akka-actor

我试图阻止让系统中的参与者共享相同名称的可能性(它们位于不同的路径上,因此InvalidActorNameException不会被抛出)

application.conf:

someactor {
  akka.remote.netty.tcp.port = 6405
  akka.cluster.auto-down-unreachable-after = 20s
  akka.cluster.seed-nodes = ["akka.tcp://mySys@127.0.0.1:2552"]
  akka.actor.provider = "akka.cluster.ClusterActorRefProvider"
}

主要:

object SomeActor extends App {
  val system  =  ActorSystem("mySys", ConfigFactory.load("application").getConfig("someactor"))
  val t = system.actorOf(Props(classOf[SomeActor]), "someActor")
}

演员:

class SomeActor extends Actor {
    val cluster = Cluster(SomeActor.system)
    override def receive = {
       case x=> println(x)
    }
}

如果使用6405端口运行一次应用程序,使用6406端口运行一次,那么应用程序将运行,但我希望它注意到系统已经包含一个名为" someActor"并阻止该电话。

我不介意将名称添加为角色或其他配置,如果它能够阻止,但我不能拥有像包含已有名称的地图的状态(或者包含带有消息传递的地图的actor或者具有像actorSelection这样的长时间运行的操作(并且无论如何,如果从多个并行地调用actorOf,它们将是安全的。

2 个答案:

答案 0 :(得分:0)

如果您真的需要100%不重叠的UUID,为什么不创建UUID分配的单一服务并在创建演员之前获取您的UUID?

您还可以在主机名,端口和演员名称上使用SHA哈希,并为每个actor使用递增的工作人员编号。

您还可以为工作人员设置群集路由器,akka会为您完成所有这些操作,您只需发送一个ActorRef即可访问工作池。

答案 1 :(得分:0)

我设法使用类型为群组的群集感知路由器(每个角色将在远程节点上运行)。 节点的作用是名称" someActor" ,我正在使用相同的名称初始化远程节点上的actor" someActor"(所以我知道这个actor的路径是什么)和路由器的totalInstances配置等于1(所以只有一个节点将成为路由器的一部分)

路由器初始化:

AppModule

远程演员:

context.actorOf(
        ClusterRouterGroup(RoundRobinGroup(Nil), ClusterRouterGroupSettings(
          totalInstances = 1, routeesPaths = List("/user/someActor"),
          allowLocalRoutees = false, useRole = Some("someActor"))).props()

和remoteActorConfig:

object RemoteActor extends App{
  val system = ActorSystem("mySys",ConfigFactory.load("remoteActorConfig"))
  system.actorOf(Props[RemoteActor], "someActor")

}

class RemoteActor extends Actor with ActorLogging{
  override def receive: Receive = {
    case x =>
      log.info(s"got: $x}")
  }
}

现在如果我要运行两次RemoteActor,运行初始化路由器的应用程序并向路由器发送广播消息 - 只有一个演员RemoterActor将接收它(并且始终是相同的)。