【关于Tomcat 并发量】
📅 2026/7/3 4:01:40
👁️ 阅读次数
📝 编程学习
探讨 Tomcat 的并发量,不能简单地给出一个固定的数字,因为Tomcat 的理论并发上限和实际业务能支撑的并发量(QPS/TPS)是两个完全不同的概念。
在当前的架构环境下(截至 2026 年,Tomcat 10.1/11 及 Java 21+ 已广泛普及),我们可以从核心配置、计算模型、最新技术(虚拟线程)以及全链路优化四个维度来彻底搞透 Tomcat 的并发量。
一、 决定 Tomcat 并发上限的核心参数
在server.xml的<Connector>标签中,有三个核心参数决定了 Tomcat 的“物理”并发上限:
maxThreads(最大工作线程数)- 含义:Tomcat 能同时处理请求的最大线程数。默认值通常是
200。 - 作用:决定了同时能处理多少个业务请求。如果请求数超过此值,多余的请求将进入等待队列。
- 建议值:根据 CPU 核数和业务类型调整。CPU 密集型建议
CPU核数 + 1;IO 密集型(如查数据库、调外部接口)建议200 ~ 800。
- 含义:Tomcat 能同时处理请求的最大线程数。默认值通常是
maxConnections(最大连接数)- 含义:Tomcat 同时能接受的最大 TCP 连接数。NIO 模式下默认
10000,APR 模式下默认8192。 - 作用:决定了 Tomcat 能“挂起”多少个客户端连接。连接建立后,会被分配给工作线程处理;如果线程满了,连接会保持在已连接状态等待线程释放。
- 含义:Tomcat 同时能接受的最大 TCP 连接数。NIO 模式下默认
acceptCount(等待队列长度)- 含义:当
maxConnections也满了时,操作系统层面等待 TCP 握手的队列长度。默认100。 - 作用:如果超过
maxConnections + acceptCount,Tomcat 将直接拒绝连接(客户端收到 Connection Refused)。
- 含义:当
💡 避坑指南:很多新手以为把maxThreads调到 2000 并发就能翻倍,这是错误的。线程过多会导致 CPU 频繁上下文切换,反而让系统崩溃。
二、 实际并发量(QPS)的计算公式
在实际业务中,Tomcat 的并发处理能力遵循利特尔法则(Little’s Law):
最大 QPS =
maxThreads/ 平均响应时间(秒)
举个例子:
- 假设
maxThreads = 200。 - 场景 A(纯内存计算,极快):平均响应时间
10ms (0.01s)。- 理论 QPS = 200 / 0.01 =20,000 QPS。
- 场景 B(涉及复杂 SQL 和外部 RPC,较慢):平均响应时间
200ms (0.2s)。- 理论 QPS = 200 / 0.2 =1,000 QPS。
结论:Tomcat 的并发瓶颈往往不在 Tomcat 本身,而在于后端应用的处理速度(尤其是数据库和第三方接口的 IO 耗时)。
三、 🚀 2026年最新突破:虚拟线程(Virtual Threads)
如果你使用的是Tomcat 10.1+ 或 Tomcat 11并且运行在Java 21+环境下,Tomcat 的并发模型发生了革命性的变化。
传统的 NIO 模型受限于 OS 物理线程数(通常几百到一千),而虚拟线程让 Tomcat 可以轻松应对数万级别的并发阻塞 IO。
开启虚拟线程的配置(server.xml):
<!-- 定义虚拟线程执行器 --><Executorname="tomcatThreadPoolVirtual"type="org.apache.catalina.core.StandardVirtualThreadExecutor"/><!-- 在 Connector 中使用 --><Connectorport="8080"protocol="org.apache.coyote.http11.Http11NioProtocol"executor="tomcatThreadPoolVirtual"maxConnections="20000"acceptCount="500"/>- 优势:在虚拟线程模式下,
maxThreads的限制被打破。当请求遇到数据库 IO 阻塞时,虚拟线程会自动让出底层载体线程(Carrier Thread),Tomcat 可以轻松维持数万个并发连接而不耗尽内存或导致 CPU 上下文切换风暴。
四、 如何提升 Tomcat 的实际并发量?(全链路优化)
要提升系统的真实并发量,单改 Tomcat 配置是没用的,必须进行“木桶效应”的全链路优化:
1. 操作系统层面 (OS)
- 文件描述符限制:执行
ulimit -n,确保其值大于 Tomcat 的maxConnections(建议设置为65535或更高)。 - TCP 队列优化:修改
/etc/sysctl.conf。net.core.somaxconn = 2048(必须大于 Tomcat 的acceptCount)net.ipv4.tcp_max_syn_backlog = 2048net.ipv4.tcp_tw_reuse = 1(允许复用 TIME-WAIT sockets)
2. 应用与数据库层面(最核心的瓶颈)
- 数据库连接池:Tomcat 有 500 个线程,但 HikariCP/Druid 只有 50 个数据库连接,那么实际并发上限就是 50。必须合理配置数据库连接池大小(通常
CPU核数 * 2 + 磁盘数是个不错的经验值)。 - 异步化改造:对于非核心链路(如发短信、写日志、发 MQ),使用
@Async或消息队列异步处理,快速释放 Tomcat 线程。 - 引入缓存:使用 Redis 拦截大量读请求,避免请求穿透到数据库耗尽 Tomcat 线程。
3. JVM 层面
- 并发量上来后,GC 压力会剧增。建议升级至G1 GC或ZGC(Java 21 中 ZGC 已默认分代,停顿时间可控制在 1ms 以内),避免因 GC Stop-The-World 导致 Tomcat 线程堆积超时。
五、 如何测试你的 Tomcat 并发量?
不要靠猜,使用压测工具在测试环境摸底:
- JMeter:最常用,适合模拟复杂的业务链路和混合场景。
- wrk / wrk2:基于 C 语言的轻量级压测工具,适合测试纯 API 的极限 QPS 和延迟分布。
- Apache Bench (ab):最简单,适合单机快速验证。
压测观察指标:
- TPS/QPS:是否达到预期。
- RT (响应时间):随着并发增加,RT 是否出现断崖式上升。
- Tomcat 线程池状态:通过 JMX 或 Spring Boot Actuator (
/actuator/metrics/tomcat.threads.busy) 观察线程是否被打满。 - 错误率:是否出现
Connection refused或Timeout。
总结
- 理论上限:由
maxConnections和acceptCount决定(通常上万)。 - 处理上限:由
maxThreads决定(通常 200~800)。 - 实际业务并发:由
maxThreads / 接口平均响应时间决定。 - 未来趋势:拥抱Java 21 + Tomcat 10.1/11 的虚拟线程,彻底解决传统线程池模型下的 IO 阻塞瓶颈。
编程学习
技术分享
实战经验