Tomcat线程池调优
Tomcat 线程池是影响并发性能的核心组件,合理配置直接影响系统吞吐量。
线程池原理
核心参数关系
YAML
请求到达 → accept-count 队列 → 线程池处理 → max-connections 限制
↓
队列满则拒绝连接
线程池执行流程
- 请求数 < min-spare:创建新线程
- min-spare < 请求数 < max:队列等待
- 请求数 > max + accept-count:拒绝连接
核心参数配置
application.yml 配置
Java
server:
tomcat:
threads:
max: 500 # 最大工作线程数
min-spare: 20 # 最小空闲线程数
accept-count: 200 # 等待队列长度
max-connections: 10000 # 最大连接数
connection-timeout: 20000 # 连接超时(ms)
参数含义说明
| 参数 | 默认值 | 说明 |
|---|---|---|
| max | 200 | 最大工作线程数 |
| min-spare | 10 | 最小空闲线程数 |
| accept-count | 100 | 等待队列长度 |
| max-connections | 8192 | 最大连接数 |
| connection-timeout | 20000 | 连接超时时间 |
线程数计算公式
CPU 密集型
Java
线程数 = CPU核心数 + 1
IO 密集型
Java
线程数 = CPU核心数 × (1 + 平均等待时间/平均工作时间)
通用推荐
Java
// 获取 CPU 核心数
int cores = Runtime.getRuntime().availableProcessors();
// IO 密集型推荐配置
int maxThreads = cores * 2 + 1; // 或更高
int minSpare = cores;
代码方式配置
自定义 Tomcat 配置
XML
@Configuration
public class TomcatThreadPoolConfig {
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> threadPoolCustomizer() {
return factory -> {
factory.addConnectorCustomizers(connector -> {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setMaxThreads(500);
protocol.setMinSpareThreads(20);
protocol.setAcceptCount(200);
protocol.setMaxConnections(10000);
protocol.setConnectionTimeout(20000);
});
};
}
}
线程池监控
Bash
@Component
public class TomcatMetrics implements MeterBinder {
@Override
public void bindTo(MeterRegistry registry) {
// 注册线程池监控指标
}
}
@RestController
public class ThreadPoolStatusController {
@GetMapping("/thread-pool")
public Map<String, Object> getThreadPoolStatus() {
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName threadPoolName = new ObjectName("Tomcat:type=ThreadPool,name=\"http-nio-*\"");
Map<String, Object> status = new HashMap<>();
status.put("maxThreads", mBeanServer.getAttribute(threadPoolName, "maxThreads"));
status.put("currentThreads", mBeanServer.getAttribute(threadPoolName, "currentThreadsBusy"));
return status;
}
}
连接器优化
NIO 模式配置
Java
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> nioCustomizer() {
return factory -> factory.addConnectorCustomizers(connector -> {
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
// NIO 模式(默认)
protocol.setPollerThreadCount(Math.max(2, Runtime.getRuntime().availableProcessors() / 2));
protocol.setSelectorTimeout(5000);
});
}
APR 模式(高性能)
text
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-native</artifactId>
<version>1.2.x</version>
</dependency>
常见问题诊断
线程池耗尽
text
# 查看线程状态
jstack <pid> | grep "http-nio" -A 5
# 分析 BLOCKED 线程
jstack <pid> | grep BLOCKED
请求队列堆积
text
@GetMapping("/queue-status")
public String getQueueStatus() {
// 通过 JMX 获取 accept-count 使用情况
return "Current queue size: " + getCurrentQueueSize();
}
注意:线程数不是越多越好,过多线程会导致上下文切换开销增加,反而降低性能。
要点总结
- 根据业务类型(CPU/IO密集)设置线程数
- max-connections 控制最大连接数,accept-count 控制队列长度
- 监控线程池状态,及时发现瓶颈
- 生产环境建议配置线程池监控告警
- 高并发场景考虑使用 NIO/APR 模式
📝 发现内容有误?点击此处直接编辑