我正在使用Scala API运行AKKA Actors(版本2.3.9)。
我有一堆异构的Actors需要每30分钟触发一次。我看到,在一次运行中,并非所有演员都被触发。这完全是随机的。每个演员都不会做任何重量级的任务。他们对NoSQL商店和一些写入进行了大量读取。不确定这里的实际问题是什么。我觉得有些地方我没有使用理想的方法。
这是代码:
val system = ActorSystem("pumpkinx-akka")
import system.dispatcher
val noOfActors = 50
val allActors = List(
system.actorOf(Props[a.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "aTriggerActor"),
system.actorOf(Props[b.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "bTriggerActor"),
system.actorOf(Props[c.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "cTriggerActor"),
system.actorOf(Props[d.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "dTriggerActor"),
system.actorOf(Props[e.actors.TriggerActor].withRouter(new RoundRobinRouter(noOfActors)), "eTriggerActor"))
def trigger = allActors.foreach(_ ! new Start)
system.scheduler.schedule(0 seconds, 30 minutes)(trigger)
system.awaitTermination()
答案 0 :(得分:4)
你创建了5个路由器,每个路由器有50个演员,所以它是250 *.actors.TriggerActor
。如果你想在一次运行中向所有250发送消息,你应该:
def trigger = (1 to 50).foreach(_ => allActors.foreach(_ ! new Start))
它将向每个路由器发送50条消息。作为它的循环,第一个消息来到路由器将转到它的第一个演员,第二个 - 到第二个,依此类推,直到第50个演员收到消息。
Just allActors.foreach(_ ! new Start)
只向50位演员之一发送消息 - 而不是向所有演员发送消息,没有广播。例如,a ! Start
只是将消息发送到a.actors.TriggerActor
P.S。我的建模:
class Trigger extends Actor {
def receive = {
case x => println(context.parent.path.name + " " + self.path.name + " " + x)
}
}
defined class Trigger
val system = ActorSystem("pumpkinx-akka")
val allActors = List(
system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "aTriggerActor"),
system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "bTriggerActor"),
system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "cTriggerActor"),
system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "dTriggerActor"),
system.actorOf(Props[Trigger].withRouter(new RoundRobinRouter(noOfActors)), "eTriggerActor"))
scala> allActors.foreach(_ ! "m") //everyone received a message
aTriggerActor $a m
bTriggerActor $a m
cTriggerActor $a m
dTriggerActor $a m
eTriggerActor $a m
scala> (0 to 5).foreach(_ => allActors(1) ! "m") //only to b-router
bTriggerActor $b m //bcdefg (round-robin)
bTriggerActor $g m
bTriggerActor $f m
bTriggerActor $d m
bTriggerActor $e m
bTriggerActor $c m
scala> (0 to 5).foreach(_ => allActors(1) ! "m") //only to b-router
bTriggerActor $h m //hijklm (round-robin)
bTriggerActor $l m
bTriggerActor $j m
bTriggerActor $k m
bTriggerActor $i m
bTriggerActor $m m
P.S。小心这些路由器内部的异常(更确切地说,在工作者内部)。如果路由器是顶级参与者 - 失败将传播给监护人,这会迫使整个系统关闭。
P.S。如果您还希望循环使用异构演员 - 请使用RoundRobinGroup
,请参阅examples