akka - 在 lagom:随着并发 http 调用的增加,线程数(akka.actor.default-dispatcher)不断增加。如何控制这种行为?
问题描述
我们观察到,在增加对我们服务的并发 http 调用时,线程数(akka.actor.default-dispatcher)不断增加(参见 visualVM 的屏幕截图)。同样在请求停止后,线程数也不会下降。其中大部分仍处于 PARK 状态。线程的这种比例增加是预期的行为吗?我们如何控制这一点并重用相同的演员或在请求服务后杀死演员。
我正在运行来自 lagom-samples 的购物车示例。
akka.actor.default-dispatcher {
executor = "fork-join-executor"
fork-join-executor {
parallelism-min = 2
parallelism-factor = 1.0
parallelism-max = 6
}
throughput = 1
}
用于 lagom 应用程序的线程分析的 VisualVM SS
编辑:使用 thread-pool-executor 作为 akka.actor.default-dispatcher 在多个(20-30)并发请求后停止服务任何请求。甚至控制台也没有响应。
default-dispatcher {
type = Dispatcher
executor = default-executor
throughput = 1
default-executor = { fallback = thread-pool-executor }
thread-pool-executor = {
keep-alive-time = 60s
core-pool-size-min = 8
core-pool-size-factor = 3.0
core-pool-size-max = 64
max-pool-size-min = 8
max-pool-size-factor = 3.0
max-pool-size-max = 64
task-queue-size = -1
task-queue-type = linked
allow-core-timeout = on
}
}
在 akka 文档的介绍中,它强调了“数以百万计的参与者可以有效地安排在十几个线程上”。那么在那种情况下,为什么我们需要创建与并发请求数成正比的线程
解决方案
你在阻止你的电话吗?例如,你在调用 Thread.sleep 吗?还是使用一些同步 IO?如果是这样,那么您所看到的完全是意料之中的。
Lagom 是一个异步框架。它提供的所有 IO 和服务间通信机制都是非阻塞的。它的线程池为非阻塞调整。如果您只使用非阻塞调用,您将看到线程池的线程数非常少,并且您不会发现事情没有响应。
但是,当您开始阻止时,所有赌注都已关闭。阻塞需要每个请求一个线程。
Akka 使用的默认调度程序是分叉连接池。它是为异步使用而设计的。如果您在其池中阻塞一个线程,它将启动另一个线程以确保其他任务可以继续。所以,这就是你看到线程池增长的原因。不要阻止,这不会发生。
另一方面,线程池执行器使用固定数量的线程。如果您对此进行阻止,则可能会导致整个应用程序陷入僵局。不要阻止,这不会发生。
推荐阅读
- c# - IAsyncEnumerator 应该
如果没有等待最后一个 MoveNextAsync() 任务,.DisposeAsync() 抛出? - anaconda - Anaconda 导航器更新问题
- rust - 在数据的单次迭代中将二进制结构解析为结构
- python - 熊猫数据框逐列
- python - 如何将我的 python 字典的每个键值对存储在 json 文件的单独行中?
- r - 如何在 R 中的 Openair 包中对 Back 轨迹聚类分析中的每个聚类重新编号和着色,以使它们一致?
- javascript - Prisma 忽略一对多自关系中的 gql 外键错误
- css - UserChrome.css 如何将 [sizemode="normal"] 与 :-moz-window-inactive 合并?
- python - ValueError:时间数据“2021-11-05 10:13:46+11:00”与格式“%y-%m-%d %H:%M:%S%z”不匹配
- rust - 有没有一种简单的方法来计算 Rust 中的布尔值?