【关于Tomcat 并发量】

📅 2026/7/3 4:01:40 👁️ 阅读次数 📝 编程学习
【关于Tomcat 并发量】

探讨 Tomcat 的并发量,不能简单地给出一个固定的数字,因为Tomcat 的理论并发上限实际业务能支撑的并发量(QPS/TPS)是两个完全不同的概念。

在当前的架构环境下(截至 2026 年,Tomcat 10.1/11 及 Java 21+ 已广泛普及),我们可以从核心配置、计算模型、最新技术(虚拟线程)以及全链路优化四个维度来彻底搞透 Tomcat 的并发量。


一、 决定 Tomcat 并发上限的核心参数

server.xml<Connector>标签中,有三个核心参数决定了 Tomcat 的“物理”并发上限:

  1. maxThreads(最大工作线程数)
    • 含义:Tomcat 能同时处理请求的最大线程数。默认值通常是200
    • 作用:决定了同时能处理多少个业务请求。如果请求数超过此值,多余的请求将进入等待队列。
    • 建议值:根据 CPU 核数和业务类型调整。CPU 密集型建议CPU核数 + 1;IO 密集型(如查数据库、调外部接口)建议200 ~ 800
  2. maxConnections(最大连接数)
    • 含义:Tomcat 同时能接受的最大 TCP 连接数。NIO 模式下默认10000,APR 模式下默认8192
    • 作用:决定了 Tomcat 能“挂起”多少个客户端连接。连接建立后,会被分配给工作线程处理;如果线程满了,连接会保持在已连接状态等待线程释放。
  3. 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 = 2048
    • net.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 GCZGC(Java 21 中 ZGC 已默认分代,停顿时间可控制在 1ms 以内),避免因 GC Stop-The-World 导致 Tomcat 线程堆积超时。

五、 如何测试你的 Tomcat 并发量?

不要靠猜,使用压测工具在测试环境摸底:

  1. JMeter:最常用,适合模拟复杂的业务链路和混合场景。
  2. wrk / wrk2:基于 C 语言的轻量级压测工具,适合测试纯 API 的极限 QPS 和延迟分布。
  3. Apache Bench (ab):最简单,适合单机快速验证。

压测观察指标

  • TPS/QPS:是否达到预期。
  • RT (响应时间):随着并发增加,RT 是否出现断崖式上升。
  • Tomcat 线程池状态:通过 JMX 或 Spring Boot Actuator (/actuator/metrics/tomcat.threads.busy) 观察线程是否被打满。
  • 错误率:是否出现Connection refusedTimeout

总结

  • 理论上限:由maxConnectionsacceptCount决定(通常上万)。
  • 处理上限:由maxThreads决定(通常 200~800)。
  • 实际业务并发:由maxThreads / 接口平均响应时间决定。
  • 未来趋势:拥抱Java 21 + Tomcat 10.1/11 的虚拟线程,彻底解决传统线程池模型下的 IO 阻塞瓶颈。