Springboot内置tomcat如何处理前端请求

我用清晰、好懂、偏源码思路给你讲一遍:SpringBoot 内置 Tomcat 接收并处理前端请求的完整流程。你可以直接对应到源码里的关键类。

一、整体流程一句话总结

  1. Tomcat 启动监听端口(默认 8080)
  2. 浏览器发 HTTP 请求 → 被 Tomcat 接收
  3. Tomcat 解析请求,封装成 Request/Response
  4. 交给 SpringMVC 的 DispatcherServlet 分发
  5. 找到对应 @Controller/@RestController 方法执行
  6. 返回结果,Tomcat 组装 HTTP 响应返回浏览器

二、详细链路(从网络到业务代码)

1. 内置 Tomcat 启动过程(SpringBoot 启动时)

  • SpringBoot 自动配置 TomcatServletWebServerFactory
  • 创建并启动 Tomcat 实例Tomcat 类)
  • 启动 Connector(监听 8080,默认 NIO 模型)
  • 注册 DispatcherServlet 到 Tomcat 的容器

关键:Tomcat 是真正的Web 服务器,SpringMVC 是跑在上面的 Servlet 应用。

2. 请求进来:Tomcat 网络层接收

  • 浏览器 TCP 三次握手 → 建立连接
  • Tomcat NIO 线程(Acceptor/Poller) 监听 socket
  • 读取 HTTP 报文(请求行、头、体)
  • 封装成 Tomcat 内部的:
    • Request(org.apache.coyote.Request)
    • Response

3. Tomcat 容器层:Engine → Host → Context → Wrapper

Tomcat 层级:

Connector → Engine → Host → Context → Wrapper → Servlet
  • Context:对应一个 Web 应用(你的 SpringBoot 项目)
  • Wrapper:对应一个 Servlet(这里就是 DispatcherServlet
  • Tomcat 调用:servlet.service(request, response)

4. 进入 SpringMVC:DispatcherServlet 核心分发

DispatcherServlet#doService()doDispatch() 是核心:

  1. 获取 HandlerMapping根据 URL 找到对应的 HandlerMethod(你写的 @GetMapping("/xxx") 方法)

  2. 获取 HandlerAdapter用来真正调用 Controller 方法(RequestMappingHandlerAdapter

  3. 执行拦截器HandlerInterceptor#preHandle

  4. 执行 Controller 方法反射调用你的接口方法,参数解析(@RequestParam/@RequestBody

  5. 处理返回值视图解析 / @ResponseBody 转 JSON(HttpMessageConverter

  6. 执行拦截器后置处理postHandle/afterCompletion

5. 回到 Tomcat 输出响应

  • SpringMVC 把结果写入 response
  • Tomcat 组装 HTTP 响应头、响应体
  • 通过 socket 写回浏览器
  • 关闭 / 复用连接

三、极简源码调用链(方便你断点追)

Acceptor/Poller 接收连接
→ CoyoteAdapter.service()
→ Request/Response 封装
→ StandardWrapperValve.invoke()
→ DispatcherServlet.service() → doDispatch()
→ HandlerMapping 找Controller
→ HandlerAdapter 执行方法
→ 返回结果写入Response
→ Tomcat 刷新输出流返回前端

四、关键角色总结

  • Tomcat Connector:负责网络 IO、HTTP 解析
  • Tomcat Container:负责 Servlet 管理、生命周期
  • DispatcherServlet:SpringMVC 中央调度器
  • HandlerMapping:URL → 控制器方法
  • HandlerAdapter:执行控制器方法
  • HttpMessageConverter:请求 / 响应数据转换(JSON 等)

Springboot内置tomcat的线程模型是怎样的

一、一句话先懂核心

内置 Tomcat 默认用 NIO 模型(非阻塞 IO),线程分三类:

  1. Acceptor 线程:接收 TCP 连接
  2. Poller 线程:监听连接的读写事件
  3. Worker(业务)线程:真正执行 Servlet、Controller 逻辑

二、完整线程模型(默认 NIO)

1. 三大线程组

(1)Acceptor 线程

  • 作用:只负责监听端口、accept 新 TCP 连接
  • 数量:默认 1 个acceptorThreadCount=1
  • 不处理请求、不读数据,只做 “接客”

(2)Poller 线程(Selector 轮询)

  • 作用:
    • 把新连接注册到 Selector
    • 轮询 OP_READ/OP_WRITE 事件
    • 有可读数据时,把任务丢给 Worker 线程池
  • 数量:默认 CPU核心数 <= 2 ? 1 : 2
  • 属于 IO 事件线程,非常轻量,不能阻塞

(3)Worker 线程池(业务线程)

  • 就是你配置的:
    server:
      tomcat:
        threads:
          max: 200       # 最大业务线程
          min-spare: 10  # 核心线程
    
  • 作用:真正执行请求:解析 HTTP、走 Filter、Servlet、Controller、返回响应
  • 这是你接口业务逻辑执行的线程
  • 阻塞、耗时、数据库操作都在这里发生

2. 一条请求完整线程流转(必背)

  1. 浏览器建连接 → Acceptor 接收
  2. Acceptor 把连接交给 Poller
  3. Poller 监听可读事件
  4. 数据到了 → Poller 把任务提交给 Worker 线程池
  5. Worker 线程 执行:
    • 解析 HTTP
    • 走 FilterChain
    • 进入 DispatcherServlet
    • 执行你的 Controller
  6. 写完响应 → Worker 线程释放回池

关键点:一个请求从头到尾,只占用一个 Worker 线程,直到响应结束。Tomcat NIO 只是IO 多路复用,不是异步 Servlet 模式。

三、三种 IO 模式对比(内置 Tomcat 支持)

1. NIO(默认,SpringBoot 推荐)

  • IO:非阻塞、多路复用(Selector)
  • 连接数高、线程数少
  • 适合:绝大多数 Web 项目

2. NIO2(APR/native 不推荐默认)

  • JDK NIO.2(AsynchronousChannelGroup)
  • 真正异步 IO
  • 用得少,SpringBoot 不默认

3. BIO(传统阻塞)

  • 一连接一线程
  • 并发高就炸,已废弃

四、关键配置 & 线程数关系

server:
  tomcat:
    # Acceptor 线程,默认1,基本不用改
    acceptor-thread-count: 1
    # Poller 线程,默认自动
    poller-thread-count: 2
    # 业务线程池(最关键)
    threads:
      max: 200        # 最大并发请求线程
      min-spare: 10
    # 等待队列(线程满了后排队的连接数)
    accept-count: 100
  • maxThreads同时处理请求的最大业务线程数
  • accept-count:连接队列长度,线程池满后,新连接在队列等着
  • 超过队列 → 直接拒绝(Connection refused)

五、容易踩坑的误区(面试高频)

  1. Tomcat NIO ≠ 异步执行

    • 只是 IO 非阻塞,Worker 线程还是同步阻塞执行整个请求
    • 想真正异步,要用:CallableDeferredResultWebFlux
  2. maxThreads 不是越大越好

    • 线程多 = 切换多、内存大
    • 一般 IO 密集型:200~500
    • CPU 密集型:接近 CPU 核心数
  3. Acceptor/Poller 很少需要改默认配置基本最优。

六、极简总结(面试直接说)

SpringBoot 内置 Tomcat 默认 NIO 线程模型

  • Acceptor:收连接
  • Poller:监听 IO 事件
  • Worker 线程池:执行业务(Controller)
  • 一个请求占用一个 Worker 线程直到返回
  • 高并发靠 IO 多路复用扛连接,靠线程池扛业务
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐