我有两个 Actor 。每个 Actor 都位于不同的 ActorSystem 中。首先缓存第二个ActorRef。第一个 Actor 这样做:
actorRef.tell(msg, self())
并向第二个参与者发送一条消息,第二个参与者进行一些处理并回复
getSender().tell(reply, self())
问题:从第一个 Actor 到第二个 Actor 的初始tell()有时需要 1-3 分钟(!)来传递消息。
除了这一条消息之外,Akka 中没有发送其他消息,这意味着邮箱是空的 - 系统正在处理单个请求。
系统详细信息:
应用程序有 500 个计划参与者,每 30 秒一次通过请求(SQS 为空)轮询 Amazon SQS(阻塞)。还有另外 330 个 Actor 在我的场景中什么也不做。所有参与者都配置了默认的 Akka 调度程序。
Box 是具有 2 个核心和 8GB RAM 的 Amazon EC2 实例。 CPU 和 RAM 利用率<5%。 JVM 有大约 1000 个线程。
初步猜测是 CPU 饥饿和线程过多导致的上下文切换。但在我的 4 核 i7 机器上,即使有 x10 数量的 actor(使用 75% 的可用 RAM),也无法在本地重现。
我怎样才能真正找到这个问题的原因呢?是否可以分析 Akka 基础设施,看看是什么导致这条消息花费如此多的时间从一个参与者传输到另一个参与者?
最佳答案
来自太多线程的上下文切换可能是此问题的根源。为了修复它,添加了以下配置:
actor {
default-dispatcher {
executor = "fork-join-executor"
fork-join-executor
{ parallelism-min = 8 parallelism-factor = 12.0 parallelism-max = 64 task-peeking-mode = "FIFO" }
}
}
因此,我们将每个物理核心的线程数从 6 个增加到 24 个。24 个足以让我们的应用程序顺利运行。在回归测试中没有观察到饥饿。
关于java - Akka - ActorRef.tell() 需要几分钟来传递消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39470841/