首页 > 解决方案 > Tomcat 线程模型 - 每个请求模型中的线程是否处理与该请求相关的所有工作?

问题描述

我知道 Servlet 容器将使用“每个请求线程”模型,但我的问题是,处理请求的线程会执行以下所有步骤吗?

  1. 从池中获取线程来处理请求,并将http请求和http响应对象传递给Servlet服务方法。
  2. 由于 I/O 操作在 DB 中完成,调用可能涉及延迟的 service/dao/ 逻辑。
  3. 返回 Http 响应
  4. 将线程返回到容器线程池

我的主要问题是,如果步骤 2 中的 I/O 操作以某种方式花费大量时间,Servlet 容器会用完池中的线程吗?还是容器只使用一个线程/线程来处理请求,然后将工作委托给另一个线程来完成其余的工作?另外我听说现在他们正在将模型更改为具有 NIO 操作的线程模型?谢谢你。

标签: javamultithreadingtomcatconcurrency

解决方案


相同的线程将用于所有事情吗?

TL;DR -没有

一旦 Servlet 容器 (Catalina) 为每个请求启动线程,该线程在请求​​-响应周期完成后立即被释放/退出(即,相应的 HTTP 请求处理程序 Servlet 方法返回)。

如果您的服务(DAO/逻辑/其他)层将阻塞线程,最终阻塞 Web 层(doGet()doPost()等),浏览器将进入空闲状态,等待响应(时间是默认或配置的),并且 Catalina (Servlet Container) 将阻塞该线程(其他请求可能成功到达);

I/O(或具体的 Request-Response)超时时间可以是默认的(60 秒,但取决于 Tomcat 版本),或者自己配置;

架构的设计,将离散的传入 HTTP 消息委托给单独的线程,具有唯一且简单的目的 - 隔离处理请求 - 响应周期。

Head First Servlet 和 JSP

Container 会为它收到的每个 servlet 请求自动创建一个新的 Java 线程。当 servlet 为该客户端的请求运行 HTTP 服务方法时,线程完成(即终止)。


更新到您更新的问题

我的问题是,处理请求的线程会执行以下所有步骤吗?

TL; DR -再次没有

Servlet 对象存在于容器中,这是一个完全独立的线程。

当 HTTP 消息(在本例中为请求)到达 Servlet 映射的端点时,会发生这种情况:

  1. Servlet Container 创建HttpServletResponseHttpServletRequest对象;
  2. 容器为该请求和响应对象分配(创建)一个新线程(重要为了隔离客户端-服务器通信。);
  3. Container 然后将这些请求和响应对象传递给 servlet 线程;
  4. Container 然后调用 Servlet API 的service()方法,并根据传入消息的类型(GETPOST等)调用相应的方法(doGet(); doPost();等);
  5. 容器不关心你拥有的任何层次或层次的架构——DAO、存储库、服务、Cherry、Apple 或其他任何东西。它将一直等到相应的 HTTP 请求处理程序方法完成(因此,如果有东西阻塞它,容器将阻塞该线程);
  6. 当处理程序方法返回时;线程被释放。

回答您的其他问题

我的主要问题是,如果步骤 2 中的 I/O 操作以某种方式花费大量时间,Servlet 容器会用完池中的线程吗?

理论上可以;但是,这意味着它应该同时阻塞所有 200 个线程,这一次(如果保持默认配置)它将不接受任何其他请求(直到某些线程释放)。

但是,这可以使用maxThreads属性进行配置,您可以选择 Tomcat 中允许的请求处理线程的阈值数量。

还是容器只使用一个线程/线程来处理请求,然后将工作委托给另一个线程来完成其余的工作?

我们已经在上面回答了这个问题。

另外我听说现在他们正在将模型更改为具有 NIO 操作的线程模型?

NIO 特定配置,它可以方便轮询线程,用于同时处理每个线程的多个连接;但是,这是一个很大且完全不同的话题。如需进一步阅读,请查看thisthis

请确保您未来的帖子不会太宽泛,在一个帖子中包含 10 个不同的问题。


推荐阅读