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 定义了 HttpServletRequest
和 HttpServletResponse
类型,以便分别处理 HTTP 请求和 HTTP 响应消息。
现在,问题变成了:Servlet Container 如何处理 HTTP 请求?
Java™ Servlet Specification
2.1 请求处理方法 一般来说,Web 容器通过在不同线程上并发执行 service 方法来处理对同一个 servlet 的并发请求; (同样重要)处理对 Web 应用程序的并发请求通常需要 Web 开发人员设计 servlet,以处理在特定时间在服务方法中执行的多个线程。另外,请注意service()
方法documentation say 的作用:
Servlet 通常在可以同时处理多个请求的多线程 Servlet 容器中运行。开发人员必须注意同步对任何共享资源的访问,例如文件、网络连接以及 servlet 的类和实例变量。
故事是这样的:
当容器看到传入的 HTTP 请求消息被映射到 Servlet 实例时,它会实例化两个对象:HttpServletResponse
和 HttpServletRequest
(每个请求都会发生这种情况);
容器然后为该请求创建(或从线程池分配)一个新线程,并通过将这些 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 线程池创建开销