我正在使用akka路由器来创建actor。设置nr-of-instances的最佳方法是什么?我的演员唯一的目的是将数据插入数据库,所以我希望尽可能多地在并行演员中运行。这只是一个任意数字?什么是最大值?
这是路由器的配置方式:
akka {
actor{
deployment {
/Master/router9 {
router = smallest-mailbox-pool
nr-of-instances = ???
}
}
}
}
答案 0 :(得分:0)
这个答案可能会让你更好地了解演员与线程的关系:How are akka actors implemented on underlying threads?
随着更多actor被创建,JVM堆将变大,但我认为路由器数量没有任何硬性最大值。我认为应根据您自己的测试选择实例数。您可用的线程数以及线程空闲的频率可能会通知您的决定。
答案 1 :(得分:0)
除了您的机器功能以及您正在运行的其他项目之外,没有真正的最大值。如果你有资源可以运行10米的资源,你可以。但是,如果你试图运行很多演员,我会说你可能要么有一个很重要的阻塞问题,要么你不明白演员如何使用游泳池。
部署的actor不包含旧线程池执行程序模式之类的线程。它只在处理消息时使用一个线程,然后在处理消息时将线程交还给调度程序。通过这种方式,调度程序重新使用线程。因此,池中actor的数量配置将取决于您是否可以从actor中获取带宽。如果您的邮件太少,将开始在收件箱中备份,如果您的邮件太多,您可能会将这些资源用于其他内容。你会惊讶于你需要很少的演员才能满足你以前用mutlithreaded执行者所做的事情。
现在,如果您在这些actor中有长时间运行的进程,那么您应该考虑将这些进程卸载到仅为了处理该长时间运行的进程而存在的actor。让我们说,例如,你的演员将主要处理普通的数据库操作,需要几毫秒才能完成,但是你发送的一些消息调用分析数据库搜索,可能需要10到30秒才能返回。在计算方面,这是永恒的。因此,对于这些进程,您最好让数据库actor分离Per-Task Actor。这是一个仅用于服务特定请求的actor,然后在发回响应后自行停止。一般过程是:
context.actorOf(Props(classOf[PerTaskActor], sender(), message)
这将创建此actor的新子actor。如果要创建顶级actor,则调用system.actorOf(...)。构造函数如下所示:
class PerTaskActor(replyTo: ActorRef, msg: MyLongProcessMessage) {
// ....
}
然后在演员内部我们运行该过程并完成后:
replyTo.tell(result)
context.stop(self)
以这种方式卸载长时间运行的任务。我建议你不要让这些演员成为脆弱演员的孩子,因为如果父演员崩溃,它会把所有孩子都带走。您可能需要一个特殊的父actor(而不是路由的actor)。