Tomcat10连接模型

介绍下 Tomcat 10(10.1.x,NIO)连接管理模型 。内容从 整体架构 → 线程/连接角色 → 生命周期 → 状态转换 → 与 Spring Boot 内嵌模式的关系 → 常见瓶颈,形成一个"可用于排障和调优"的模型


一、整体架构总览(Tomcat 10 NIO)

Tomcat 10 默认使用 HTTP/1.1 NIO ConnectorHttp11NioProtocol),其连接管理是事件驱动 + 线程池执行模型:

复制代码
           ┌───────────┐
           │ Acceptor  │   接受 TCP 连接
           └─────┬─────┘
                 │
                 ▼
       ┌───────────────────┐
       │   Endpoint        │
       │  (NioEndpoint)    │
       └─────┬─────────────┘
             │
   ┌─────────▼─────────┐
   │      Poller       │   连接管理核心(Selector)
   │  (connection pool)│
   └─────────┬─────────┘
             │ 事件触发
             ▼
   ┌─────────────────────┐
   │   Executor /        │
   │   Worker Threads    │   执行业务
   └─────────────────────┘

核心思想
连接(Socket)与线程(Request 处理)分离

连接由 Poller 管,线程只在"真正处理请求"时使用。


二、核心组件与职责

1️⃣ Connector / Endpoint

  • 负责网络层

  • 参数:maxConnections, acceptCount, connectionTimeout

  • 在 Tomcat 10 中默认实现是:

    org.apache.tomcat.util.net.NioEndpoint

Endpoint 管三件事:

  • Acceptor(接连接)
  • Poller(管连接)
  • SocketWrapper / Buffer 池

2️⃣ Acceptor(接入层)

职责

  • 调用 ServerSocketChannel.accept()
  • 创建 SocketChannel
  • 注册到 Poller

关键参数

  • acceptCount:backlog 队列
  • 受 OS somaxconn 影响

特点

  • 不处理请求
  • 只负责把连接交给 Poller
  • 通常 1 个线程

3️⃣ Poller(连接管理核心)

职责(非常重要)

  • 维护 Selector

  • 管理所有活跃 Socket

  • 监听事件:

    • READ
    • WRITE
    • TIMEOUT
  • 管理 keep-alive

  • 管理 Socket 状态机

Poller = Tomcat 的"连接池"

  • 所有 Socket(包括 idle)都在这里
  • maxConnections 限制

CLOSE_WAIT / ESTABLISHED / IDLE 都属于 Poller 管理范围


4️⃣ Executor / Worker 线程池

职责

  • 处理 HTTP 请求
  • 调用 Filter / Servlet / Spring MVC
  • 不管理连接生命周期

关键参数

  • maxThreads
  • minSpareThreads

三、连接生命周期(一次完整 HTTP/1.1)

Step 1:建立 TCP 连接

复制代码
Client → SYN
Server → SYN+ACK
Client → ACK

→ Acceptor 接收

→ 注册到 Poller

→ 状态:ESTABLISHED (IDLE)


Step 2:接收请求数据

  • Poller 监听到 READ 事件
  • 创建 Http11Processor
  • 投递给 Executor

Step 3:业务处理

  • Worker 线程处理:

    • Filter
    • Servlet
    • Spring Controller
  • 构建 Response


Step 4:响应写回

  • Poller 负责 WRITE
  • Response 写回 socket

Step 5:连接去向

✔ keep-alive

复制代码
IDLE → Poller

✔ 非 keep-alive

复制代码
close() → TIME_WAIT

四、连接状态机(简化)

复制代码
NEW
 ↓
ESTABLISHED
 ↓
READING
 ↓
PROCESSING (worker)
 ↓
WRITING
 ↓
IDLE (keep-alive)
 ↓
CLOSED / TIME_WAIT

⚠️ 如果:

  • 客户端先 close
  • Tomcat 未 close

CLOSE_WAIT


五、Tomcat 10 的关键限制点

1️⃣ maxConnections(连接池上限)

  • 默认:8192

  • 包含:

    • idle keep-alive
    • 正在处理
    • CLOSE_WAIT(未 close)

超过后:

  • 新连接进入 acceptCount
  • 再超 → 拒绝连接

2️⃣ maxThreads(业务并发上限)

  • 你配置:800
  • 只限制"正在处理的请求"
  • 不限制连接数

3️⃣ acceptCount(缓冲区)

  • 你配置:1000
  • TCP 层 backlog

六、Spring Boot 内嵌 Tomcat 的映射关系

yaml 复制代码
server:
  tomcat:
    max-connections: 8192
    accept-count: 1000
    threads:
      max: 800
Spring Boot Tomcat
max-connections Endpoint.maxConnections
accept-count Acceptor backlog
threads.max Executor.maxThreads

七、Tomcat 10 的几个"反直觉点"(很重要)

❗ 1. 连接多 ≠ 线程多

  • 10k 连接
  • 800 线程
  • 完全正常

❗ 2. CLOSE_WAIT 会吃掉连接池

  • 不会自动释放
  • 是服务端 bug 信号

❗ 3. Poller 不等于线程池

  • Poller 是 I/O 事件循环
  • Executor 是业务执行

八、常见问题与调优方向

你遇到的:

CLOSE_WAIT ≈ 3700 → 服务不可用

在 Tomcat 10 模型下意味着:

  • Poller 的连接池被"半死连接"占满
  • Acceptor 无法接新连接
  • 表现为端口存在但无响应

九、一句话总结(工程视角)

Tomcat 10 采用"事件驱动连接管理 + 线程池业务处理"的模型,Poller 统一管理 Socket 生命周期,Executor 只在请求处理阶段介入;任何 CLOSE_WAIT 的累积都会直接耗尽连接池,导致服务雪崩。

相关推荐
我真会写代码1 天前
SSM(指南一)---Maven项目管理从入门到精通|高质量实操指南
java·spring·tomcat·maven·ssm
DN金猿1 天前
接口路径正确,请求接口却提示404
java·tomcat
vx1_Biye_Design2 天前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
qq_297574672 天前
SpringBoot项目长时间未访问,Tomcat临时文件夹被删除?解决方案来了
spring boot·后端·tomcat
计算机毕设指导63 天前
基于微信小程序的校园二手交易系统【源码文末联系】
java·spring boot·spring·微信小程序·小程序·tomcat·maven
Filotimo_3 天前
Tomcat的概念
java·tomcat
lang201509283 天前
Tomcat8RunnerCli:可执行WAR的命令行门面
tomcat
人道领域3 天前
SSM框架从入门到入土(SpringFrameWork)
java·spring boot·tomcat
belldeep4 天前
Java:Tomcat 9 和 mermaid.min.js 10.9 上传.csv文件实现 Markdown 中 Mermaid 图表的渲染
java·tomcat·mermaid·去除flexmark
lang201509284 天前
Tomcat Maven插件:部署与卸载的架构设计
java·tomcat·maven