【问题标题】:Parallel Thread Contention At High Load高负载下的并行线程争用
【发布时间】:2020-06-22 13:40:39
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 也许我是个笨蛋,但我对TPS这个词不熟悉?
  • 哦,对不起。每秒事务数。

标签: java multithreading concurrency project-reactor reactor


【解决方案1】:

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

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

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

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

【讨论】:

  • 我切换到并行时已经有了响应。在并行线程上不进行任何 I/O 调用。您是说 POJO 操作等正在阻塞调用吗?此外,我所有的 I/O 调用都是非阻塞的。最后,无法在Tomcat的线程上启动管道,所以需要进行线程切换。
猜你喜欢
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 2018-05-23
  • 1970-01-01
  • 2011-07-19
  • 2023-03-10
  • 1970-01-01
  • 2015-03-25
相关资源
最近更新 更多