Tomcat 连接器体系结构、线程池和异步 servlet

我想了解Tomcat的BIO和NIO连接器的线程模型。我引用了官方Tomcat 7文档的连接器,可以在这里找到。基于它,这就是我所怀疑的:

  • acceptorThread(s): 这是单个或最多 2 个线程(如文档中所述),仅负责接受传入的连接。这可以使用 acceptorThreadCount 进行配置,并且建议将两个以上的计算机用于多 CPU 计算机 -
    • 这是为什么呢?
    • 这是否意味着同时打开的连接数随 CPU 数与服务器系统上允许的打开文件描述符数的数目而增加?
  • 最大连接数
    • 此设置与 acceptCount 与系统上打开的文件描述符数之间的关系是什么。
    • 为什么 NIO 连接器 (10000) 的默认值比 BIO ( = maxThreads) 的默认值高得多?
  • acceptCount :这是所有请求处理线程都忙时的请求队列。
    • 当请求被放入此队列时,是否也为其分配了文件描述符?还是仅在主动处理请求时,它是否使用文件描述符?
  • 请求处理线程 :此池中的线程数由 maxThreadsminSpareThreads 属性配置。
    • 此线程池和接受器线程之间的关系是什么?接受器线程是否生成此池中的线程?
    • 据我所知,NIO模型在请求处理线程方面比BIO模型更有效。它是如何实现这种效率的?
    • 正如我在各种来源中读到的那样,NIO模型中的线程遵循BIO模型的线程每请求范式,而不是每个连接的线程范例。此外,在 NIO 连接器模型中,实际的请求处理被委托给不同的应用程序监视线程,而服务器的请求处理线程返回到线程池 - 自由接受更多连接。那么,这是否意味着NIO模型的好处只有在与服务器的连接具有HTTP Keep-Alive性质或者应用程序使用Servlet 3.0的异步处理功能时才会显现出来?
  • Servlet 3.0
    • 使用 Servlet 3.0 时,应用程序 Servlet 线程池的大小应该是多少(相对于连接器线程池大小)才能达到最佳效率?
    • 当使用BIO模型和这个模型一起使用时,在处理请求的方式上会有什么不同(假设连接器线程仍将使用每个连接模型的线程)?

请注意:所有关于tomcat 7的讨论。


答案 1
  • acceptorThread(s): 这是单个或最多 2 个线程(如文档中所述),仅负责接受传入的连接。这可以使用 acceptorThreadCount 进行配置,并且建议将两个以上的计算机用于多 CPU 计算机 -

    这是为什么呢?

接受连接是一项成本非常低的操作,因此将多个线程专用于此任务是没有意义的。

Does this imply that the number of simultaneous open connections 
scales with the number of cpus versus the number of open file descriptors 
allowed on the server system ?

不,它没有,因为它在CPU方面是一个非常低成本的操作。至于文件描述符,每个接受的连接都将使用一个文件描述符,因此服务器可以接受的最大连接数受可用文件描述符数量的限制。

  • 最大连接数

    此设置与 acceptCount 与系统上打开的文件描述符数之间的关系是什么。

maxConnections 不能高于系统上打开的文件描述符的数量。请记住,其他进程也使用文件描述符,因此可能希望在可用文件描述符方面保守使用maxConnections,假设maxConnections<文件描述符/ 2。

Why is the default value for this so much higher for the NIO connector 
( 10000 ) than for the BIO ( = maxThreads ) ?

这是因为在NIO中,单个处理所有IO,而在BIO中,服务器需要创建/使用单独的每个线程连接。

  • acceptCount :这是所有请求处理线程都忙时的请求队列。

    当请求被放入此队列时,是否也为其分配了文件描述符?

是的,这是正确的,连接请求被接受,但服务器尚未准备好为请求提供服务,因此连接被放置在队列中。这样做是为了防止 TCP/堆栈超时连接请求,从客户端的角度来看,这些请求可能看起来像服务器关闭。换句话说,服务器说“我在这里,一旦我有资源去做,就会处理你的请求”。

还是仅在主动处理请求时,它是否使用文件描述符?

不。

希望这有帮助。

问候

斯拉瓦·伊梅舍夫


答案 2