Tomcat 个应用中的额外线程池

Additional thread pools within Tomcat apps

我使用与 Apache Tomcat 一起运行的 Java 网络应用程序。 Tomcat 线程池的最大线程数为 800,minSpareThreads 为 25。在运行时,它通常在给定时间大约有 400 运行 个线程。

假设我必须在我的 Tomcat 应用程序中执行一项计算量大的非阻塞任务,其中 ForkJoinPool.commonPool 用于更有效地解决任务。

因为我的 Apache Tomcat 应用程序中已经有一个大线程池,Tomcat 线程池是否会降低我使用 ForkJoinPool(或任何线程池,因为那很重要)在我的 Tomcat 应用程序中? 运行 Tomcat 线程池与 ForkJoinPool 一起的性能成本能否抵消使用 ForkJoinPool 的性能提升,因为现在,线程数将比 CPU 多得多?

向 Apache Tomcat 应用程序添加任何类型的额外线程池是否会影响整个应用程序的性能?

这个问题很难给出一个笼统的答案,因为它在很大程度上取决于具体的工作量。测试和分析您自己的应用程序是无可替代的。但是,这里有一些事情需要考虑。

运行 单独线程池中的 CPU 绑定任务根本不能保证给您带来任何性能优势。它可能有益的主要原因有两个:

  1. 当一个线程在单独的线程上将任务提交给 运行 的执行程序时,它可以继续并发执行其他工作。
  2. 如果任务可以分解为多个子任务,每个子任务 运行 在单独的线程上,您可以利用多个 CPU 核心上的并行处理来更快地完成它。

拥有更多线程的成本是:

  1. 分配给每个线程的内存。
  2. 当 OS 将 CPU 时间从一个线程重新分配到另一个线程时,由上下文切换引起的延迟。

Tomcat 请求线程池大小的默认值是基于线程花费大量时间阻塞 I/O 的常见情况:通过网络读取请求、进行数据库查询和更新,并将响应写回客户端。这意味着这些线程无法利用所有可用的 CPU 时间,拥有比 CPU 核心更多的线程是有益的,这样阻塞的线程可以被需要 [=36] 的线程抢占=]时间。

所以,一个大问题是什么在调用这些任务:它是一个请求线程吗?如果是这样,该请求线程在任务进行时做什么?是否正在阻止 I/O 调用?难道只是等待任务完成?

如果您的大部分请求都在调用这些 CPU 密集型任务之一,然后阻塞等待它完成,并且如果这些任务没有拆分成 运行 在多个并行核,那么您可能无法从单独线程池中的 运行ning 任务中获得任何好处。最好避免在请求线程上进行上下文切换和 运行 这些任务的开销。如果您的服务处理的大部分请求都是 运行 这类任务,那么您可能希望减少 Tomcat 线程池中的请求线程数,因为您的实际并发性将受限于可用的CPU 时间。您最终可能会遇到大量等待线程和高响应延迟。然后,这些请求可能会在客户端超时,从而在最终失败的请求上浪费大量服务器资源。