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 的累积都会直接耗尽连接池,导致服务雪崩。

相关推荐
阿干tkl11 小时前
Tomcat文件上传及下载
java·tomcat
Overt0p21 小时前
抽奖系统(4)
java·spring boot·tomcat
用户6135411460161 天前
Tomcat Connectors 1.2.32 源码编译安装教程(含 mod_jk 配置步骤)
tomcat
hgz07101 天前
MyBatis插件(拦截器)
java·tomcat
Howie Zphile1 天前
TOMCAT跑死服务器,怎么限制TOMCAT使用资源
服务器·tomcat·firefox
计算机毕设指导62 天前
基于微信小程序的设备报修系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
计算机毕设指导63 天前
基于微信小程序的智慧社区娱乐服务管理系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·娱乐
getapi3 天前
/usr/local/apache-tomcat-9.0.71/logs/catalina.out占用了118G
tomcat·apache·firefox
weixin_440730503 天前
Nginx、Apache和tomcat的简单了解。
nginx·tomcat·apache