首页 > 解决方案 > 高负载下的并行线程争用

问题描述

我有一个四核机器。在高负载下,响应时间非常糟糕。这很明显,因为工作队列在高负载下增长,而 4 个并行线程只能消耗这么快。

Mono.just(stream)
    .flatMap(handler::handleRequest)
    .subscribeOn(Schedulers.parallel())
    .subscribe(this::response) 

类似地,当我得到一个I/O调用的响应时,我会这样做,.publishOn(Schedulers.parallel())以便在 CPU 调整的线程上处理响应。

我正在考虑使用有界弹性调度程序来启动我的管道并将并行线程仅用于高度 CPU 密集型任务(POJO 操作和哈希计算)。所以基本上,我在弹性线程上启动我的管道并在弹性线程上处理响应。

我使用无限弹性调度程序对我的应用程序进行了基准测试,并且堆大小爆炸了。但是,等待时间肯定会更短。但是,如果我创建了太多线程,调度开销有时会掩盖较低的等待时间。

如何优化我的应用程序?我的目标是每个 800 TPS 左右JVM。推荐创建那么多线程吗?

标签: javamultithreadingconcurrencyproject-reactorreactor

解决方案


同样,当我收到 I/O 调用的响应时,我会执行 .publishOn(Schedulers.parallel()) 以便在 CPU 调整的线程上处理响应。

那就是问题所在。你永远不应该在由开始的线程中进行阻塞调用Schedulers.parallel()(你可以使用http://github.com/reactor/BlockHound,当你这样做时会抛出错误)。

所以基本上,我在弹性线程上启动我的管道并在弹性线程上处理响应。

无需“在弹性线程上启动管道”。只需“正常”启动它,然后将阻塞调用卸载到Schedulers.boundedElastic().


推荐阅读