1、跳出一个误区:SpringBoot 不处理任何请求
Spring 本身并不进行 Web 的处理,无论是 TCP 连接也好还是请求和响应也好,这些都是在 Spring 以外的部分完成的,例如 Tomcat,所以默认的 SpringBoot 将会集成 Tomcat 内嵌容器。
Controller 中收到的请求,都是经过 Tomcat 容器解析后交给 Servlet,再由 Servlet 转交给 Controller 的。
2、Tomcat 是如何处理请求的?
一个 Tomcat 也就是一个服务器,服务器将会包含一个或多个 Service,这也就是在 Tomcat 中运行的各个 web 服务,而组成 web 服务的组件,分别为 Connector 和 Container,在 Tomcat 启动 Service 的时候就会初始化它们。
其中 Connector 的作用,顾名思义,用来处理网络的各类链接,对于 Http 服务,那当然是 TCP 连接了。
Connector 的连接建立之后,是能够传输数据的,这些数据将会通过 Servlet 接口的具体实现来进行处理。Servlet 中,可以得到输入流和输出流,如果使用 HttpServlet,那么你可以直接得到 Request 和输出 Response。
Tomcat 采用多线程的方式来处理请求。每当有一个请求到达 Tomcat 服务器时,Tomcat 会为该请求分配一个线程来处理。
在 Tomcat 中,有一个线程池(ThreadPool)用于管理处理请求的线程。当有新的请求到达时,Tomcat 会从线程池中获取一个空闲线程来处理该请求。处理完请求后,该线程会被释放回线程池,以便处理其他请求。
采用多线程模型的好处是能够同时处理多个请求,提高服务器的并发性能。每个线程独立处理一个请求,互不干扰,可以并行执行,提高了服务器的吞吐量。
然而,多线程模型也有一些注意事项。由于每个线程都需要占用一定的系统资源,当并发请求数量过大时,可能会导致服务器资源耗尽,影响性能。因此,在配置 Tomcat 时,需要根据服务器的硬件配置和预期的并发量来调整线程池的大小,以达到最佳的性能和资源利用率。
当请求数量超过 Tomcat 的线程池大小时,多余的请求会被放入一个请求队列中等待处理。
Tomcat 中的请求队列被称为"任务队列"(Task Queue),它是一个先进先出(FIFO)的队列数据结构。当线程池中的线程已经全部被占用时,新的请求会被放入任务队列中等待处理。
任务队列的大小可以通过配置参数进行调整,具体取决于服务器的硬件资源和预期的并发量。如果任务队列已满,而且没有空闲的线程可用来处理新的请求,那么新的请求将会被拒绝,客户端可能会收到连接超时或服务器忙的错误信息。(Tomcat 调优)
3、 Spring 在整个链路中做什么事呢?
Spring Web 定义了一个 DispatcherServlet,这个东西会接收 Request,并且根据用户的配置,转到 Spring 中的 Controller 进行处理。
DispatcherServlet 不在乎这个 Request 的连接,甚至不在乎这个 Request 是谁提供的,只要有一个 Web 服务器,或者说 web 容器提供符合要求的 Request,Spring 的 Web 模块就能使用它,并且把它分发到自己容器内的 Controller 中。
通常来说,Request 里面包含了 InputStream 和 OutputStream,利用他们就足以完成响应了。
这些被 Spring 分发的 Request,他们的连接也当然是被 web 容器管理的,这样的话,是不是一个请求使用一个线程,这个由 web 的容器决定的而不是 Spring。
标签:http,SpringBoot,Tomcat,处理,Spring,Request,线程,请求 From: https://www.cnblogs.com/gapu/p/17552913.html