Spring Boot 是不是创建 N 个线程来处理 N 个 API 请求?

Posted

技术标签:

【中文标题】Spring Boot 是不是创建 N 个线程来处理 N 个 API 请求?【英文标题】:Does Spring Boot create N threads to process N API requests?Spring Boot 是否创建 N 个线程来处理 N 个 API 请求? 【发布时间】:2021-06-07 01:44:10 【问题描述】:

我正在使用 Spring Boot 2.5 编写 HTTP API 服务器。我对 Spring Boot 如何处理多个 HTTP 请求感到有些困惑?

假设 Spring Boot 应用程序一次处理 N 个请求。它是否为 Spring Boot 应用程序创建 N 个线程?

【问题讨论】:

类似于***.com/questions/46893237/… 【参考方案1】:

Spring Boot 会创建 N 个线程来处理 N 个请求吗?

是的。

然而,(1) 这并不是 Spring Boot 的一个特别的特性,(2) 您真的不应该担心自己在基于 Web 容器的应用程序中管理线程(虽然,有对内部结构感兴趣,很好)。

Spring Boot 的 HTTP 通信基于 Servlet API,即 Spring Boot 使用 Servlet Container(即作为您的应用服务器在后台运行的)来处理 HTTP 通信,并且通常,服务 HTTP Spring Boot 使用 Tomcat,作为默认的 Servlet 容器

另一方面,Servlet API 定义了 HttpServletRequestHttpServletResponse 类型,以便分别处理 HTTP 请求和 HTTP 响应消息。

现在,问题变成了:Servlet Container 如何处理 HTTP 请求

Java™ Servlet Specification

2.1 请求处理方法 一般来说,Web 容器通过在不同线程上并发执行 service 方法来处理对同一个 servlet 的并发请求; (同样重要)处理对 Web 应用程序的并发请求通常需要 Web 开发人员设计 servlet,以处理在特定时间在服务方法中执行的多个线程。

另外,请注意service() 方法documentation say 的作用:

Servlet 通常在可以同时处理多个请求的多线程 Servlet 容器中运行。开发人员必须注意同步对任何共享资源的访问,例如文件、网络连接以及 servlet 的类和实例变量。

故事是这样的:

    当容器看到传入的 HTTP 请求消息被映射到 Servlet 实例时,它会实例化两个对象:HttpServletResponseHttpServletRequest(每个请求都会发生这种情况);

    容器然后为该请求创建(或从线程池分配)一个新线程,并通过将这些 HttpServletRequest 和 HttpServletResponse 对象传递给该方法,在该新线程中调用 Servlet 的 service(..) 方法。

如果不是这样设计的,服务器会阻止每个 HTTP 消息的执行,直到后者完成。

请注意:

与请求关联的线程可能处于空闲状态的常见情况有两种:

    线程需要等待资源可用或处理数据,然后再构建响应。例如,应用程序可能需要在生成响应之前查询数据库或从远程 Web 服务访问数据; 线程在生成响应之前需要等待一个事件。例如,应用程序可能必须等待 JMS 消息、来自另一个客户端的新信息或队列中可用的新数据,然后才能生成响应。

【讨论】:

servlet 容器不创建新线程,发生的情况是线程池(默认为 200 个)线程,这些线程(重新)用于处理请求。因此,如果有 201 个并发请求,最后一个请求要么失败,要么被放入队列以供稍后处理。 只是编辑问题.. 使其更精确;但是,如果池耗尽,如果我没记错的话,更大/更新的池会被实例化。否则 200 个并发请求可以锁定应用程序。 这取决于策略,甚至创建更多线程可能会挂起应用程序。

以上是关于Spring Boot 是不是创建 N 个线程来处理 N 个 API 请求?的主要内容,如果未能解决你的问题,请参考以下文章

使用spring-boot创建定时任务。同时创建多线程执行定时任务。

在 N 个并行保存请求后 Spring Boot Rest Api 卡住了

Spring Boot 嵌入式 Tomcat 线程池创建开销

Spring Boot MVC 控制器是多线程的吗?

Spring Boot + Quartz:“请求的 bean 当前正在创建中:是不是存在无法解析的循环引用?”

Spring Boot 定时任务单线程和多线程