我一直在研究Akka Actor模型。我有一个用例,其中有1000多个参与者处于活动状态,并且我必须处理这些参与者。我想到了通过application.conf中定义的配置来控制线程数。
但是没有。在应用程序中创建的调度程序线程的使用使我无助于调整调度程序配置。每次我重新启动应用程序时,都会看到创建了不同数量的调度程序线程(每次启动应用程序后,我都会通过线程转储进行检查)。
即使线程数也不等于我在并行度-min中定义的线程数。由于线程数量少,我的应用程序处理速度非常慢。 在检查号。通过以下代码查看我机器的核心:
Runtime.getRuntime()。availableProcessors();
它显示40。但是没有。即使我将并行度配置为500,创建的调度程序线程数也少于300。
以下是我的application.conf文件:
consumer-dispatcher {
type = "Dispatcher"
executor = "fork-join-executor"
fork-join-executor {
parallelism-min = 500
parallelism-factor = 20.0
parallelism-max = 1000
}
shutdown-timeout = 1s
throughput = 1
}
我是否可以知道akka将在内部基础上创建调度程序线程,以及如何增加调度程序线程数以增加参与者的并行处理?
答案 0 :(得分:0)
来自discuss.lightbend.com的X-Post
首先让我直接回答问题。
fork-join-executor
将由java.util.concurrent.forkJoinPool
池支持,该池的并行性设置为调度程序配置中的隐含并行性。 (并行因子*处理器,但不大于max或小于min)。因此,根据您的情况,为800。
尽管我不是ForkJoinPool
实施的专家,但ForkJoinPool
的Java实施来源说:“所有工作线程的创建都是按需的,由任务提交触发,替换了解雇的工人和/或补偿被封锁的工人。”而且它具有getActiveThreads()
之类的方法,因此很明显ForkJoinPool
并不是天真的创造了一个庞大的工人池。
换句话说,您所看到的是预期的:它只会根据需要创建线程。如果确实必须有一个巨大的工作线程池,则可以创建一个固定池大小为800的线程池执行器。这将为您提供所需的实现。
但是,在您这样做之前,我认为您完全错过了演员和Akka的观点。人们喜欢actor的原因之一是,它们比线程轻巧得多,并且可以为您带来比线程更多的并发性。 (还请注意,并发!=并行性,如概念文档中所述。)因此,尝试创建800个线程池来支持1000个参与者是非常浪费的。在akka docs introduction中突出显示“可以在多个线程上有效地安排数百万个参与者”。
在不知道应用程序的情况下(例如,如果您有阻塞行为),我无法确切告诉您需要多少线程,但是默认值(并行度为20)可能就可以了。可以确定基准,但是我真的不认为线程太少会出现问题。 (您观察到的ForkJoinPool
行为似乎可以证实这一点。)