java - 高负载下的并行线程争用
问题描述
我有一个四核机器。在高负载下,响应时间非常糟糕。这很明显,因为工作队列在高负载下增长,而 4 个并行线程只能消耗这么快。
Mono.just(stream)
.flatMap(handler::handleRequest)
.subscribeOn(Schedulers.parallel())
.subscribe(this::response)
类似地,当我得到一个I/O
调用的响应时,我会这样做,.publishOn(Schedulers.parallel())
以便在 CPU 调整的线程上处理响应。
我正在考虑使用有界弹性调度程序来启动我的管道并将并行线程仅用于高度 CPU 密集型任务(POJO 操作和哈希计算)。所以基本上,我在弹性线程上启动我的管道并在弹性线程上处理响应。
我使用无限弹性调度程序对我的应用程序进行了基准测试,并且堆大小爆炸了。但是,等待时间肯定会更短。但是,如果我创建了太多线程,调度开销有时会掩盖较低的等待时间。
如何优化我的应用程序?我的目标是每个 800 TPS 左右JVM
。推荐创建那么多线程吗?
解决方案
同样,当我收到 I/O 调用的响应时,我会执行 .publishOn(Schedulers.parallel()) 以便在 CPU 调整的线程上处理响应。
那就是问题所在。你永远不应该在由开始的线程中进行阻塞调用Schedulers.parallel()
(你可以使用http://github.com/reactor/BlockHound,当你这样做时会抛出错误)。
所以基本上,我在弹性线程上启动我的管道并在弹性线程上处理响应。
无需“在弹性线程上启动管道”。只需“正常”启动它,然后将阻塞调用卸载到Schedulers.boundedElastic()
.
推荐阅读
- sql - 如何显示与按另一列分组的 max() 相关的值
- javascript - Material ui:悬停时打开和关闭(多个)选择组件 - 不是点击
- objective-c - 重新启动 macOS Big Sur 后如何检测 USB 调制解调器
- asp.net-core - 如何使图书馆在服务器上工作?ASP.NET 核心
- c++ - 错误:没有以 NULL 作为参数调用构造函数的匹配函数?
- c# - Unity FAILURE:构建失败并出现异常
- apache-flink - 后期数据丢失的 Flink 端输出
- ruby-on-rails - 是否可以在 RoR 项目的根级别为不同的应用程序保留不同的文件夹
- mysql - MySQL查询将分隔字符串值拆分为单独的列
- wordpress - 如何修复 babel-polyfill 和 WordPress 的错误?