前置说明
适配:SpringBoot3.x + Java17 + HikariCP + Redis (Lettuce) + 自定义线程池
原则:不是无脑调大参数,偏向生产高性能、防雪崩、适合 IO 密集型后端(数据库 + Redis 混合 IO); 区分:业务线程池(不混用 Tomcat 线程)、Hikari 连接池、Lettuce Redis 池 依赖:spring-boot-starter-data-redis、spring-boot-starter-jdbc /mybatis-spring-boot-starter
1. application.yml(直接复制)
# ===================== 服务基础 & Tomcat优化 =====================
server:
port: 8080
tomcat:
threads:
max: 200 # Tomcat最大工作线程,IO密集建议 150~250,CPU密集调低
min-spare: 20 # 核心空闲线程
accept-count: 100 # 排队队列长度,溢出直接拒绝
connection-timeout: 10000
max-connections: 800
spring:
# ===================== HikariCP 数据库连接池【重点最优配置】=====================
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&useSSL=false
username: root
password: 123456
hikari:
pool-name: HikariCP-DB-POOL
maximum-pool-size: 12 # 黄金经验值:CPU核数*2 + 磁盘数;不要盲目开大!数据库连接很贵
minimum-idle: 6 # 最小空闲,不建议等于max,避免抖动
idle-timeout: 300000 # 空闲连接5分钟释放
max-lifetime: 1800000 # 连接最大存活30min,比数据库wait_timeout小
connection-timeout: 3000 # 获取连接超时3s,快速失败,不要设很大
validation-timeout: 2000
leak-detection-threshold: 5000 # 连接泄露检测,超过5s拿连接不归还打印告警
# ===================== Redis Lettuce 连接池(SpringBoot3默认Lettuce,不用Jedis)=====================
redis:
host: 127.0.0.1
port: 6379
password: ""
database: 0
timeout: 2000ms
lettuce:
pool:
max-active: 16 # 最大连接
max-idle: 8
min-idle: 4
max-wait: 1000ms
shutdown-timeout: 100ms
# ===================== 自定义业务线程池配置项(后面Java配置类读取)=====================
custom-thread-pool:
core-pool-size: 8
maximum-pool-size: 32
queue-capacity: 200
keep-alive-seconds: 60
thread-name-prefix: biz-pool-
allow-core-thread-timeout: false
2. 自定义线程池配置类【直接复制】
重要:禁止直接用 Executors,使用 ThreadPoolExecutor,拒绝策略用 AbortPolicy / 自定义告警策略 用途:异步业务、批量处理、非主链路任务;DB 操作必须从 Hikari 拿连接,不要在线程池里无限开连接
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.*;
@Configuration
@ConfigurationProperties(prefix = "custom-thread-pool")
public class BizThreadPoolConfig {
private Integer corePoolSize;
private Integer maximumPoolSize;
private Integer queueCapacity;
private Integer keepAliveSeconds;
private String threadNamePrefix;
private Boolean allowCoreThreadTimeout;
/**
* 业务IO线程池,用于异步任务、批量查询、消息消费等
* 【不用于Tomcat主请求,和web线程隔离】
*/
@Bean("bizTaskExecutor")
public Executor bizTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maximumPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setThreadNamePrefix(threadNamePrefix);
executor.setAllowCoreThreadTimeOut(allowCoreThreadTimeout);
// 拒绝策略:队列满+线程满,直接抛异常,防止堆积拖垮服务;生产可替换为自定义告警策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
executor.initialize();
return executor;
}
// ========== getter & setter ==========
public Integer getCorePoolSize() {
return corePoolSize;
}
public void setCorePoolSize(Integer corePoolSize) {
this.corePoolSize = corePoolSize;
}
public Integer getMaximumPoolSize() {
return maximumPoolSize;
}
public void setMaximumPoolSize(Integer maximumPoolSize) {
this.maximumPoolSize = maximumPoolSize;
}
public Integer getQueueCapacity() {
return queueCapacity;
}
public void setQueueCapacity(Integer queueCapacity) {
this.queueCapacity = queueCapacity;
}
public Integer getKeepAliveSeconds() {
return keepAliveSeconds;
}
public void setKeepAliveSeconds(Integer keepAliveSeconds) {
this.keepAliveSeconds = keepAliveSeconds;
}
public String getThreadNamePrefix() {
return threadNamePrefix;
}
public void setThreadNamePrefix(String threadNamePrefix) {
this.threadNamePrefix = threadNamePrefix;
}
public Boolean getAllowCoreThreadTimeout() {
return allowCoreThreadTimeout;
}
public void setAllowCoreThreadTimeout(Boolean allowCoreThreadTimeout) {
this.allowCoreThreadTimeout = allowCoreThreadTimeout;
}
}
3. 使用示例(注入线程池)
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.util.concurrent.Executor;
@Service
public class BizService {
private final Executor bizTaskExecutor;
public BizService(@Qualifier("bizTaskExecutor") Executor bizTaskExecutor) {
this.bizTaskExecutor = bizTaskExecutor;
}
public void submitTask(){
bizTaskExecutor.execute(() -> {
// 异步业务逻辑
});
}
// @Async 注解方式,指定线程池
@Async("bizTaskExecutor")
public void asyncMethod(){
}
}
4. 配套 POM 关键依赖(SpringBoot3 + Java17)
<dependencies>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- JDBC + HikariCP(boot自带hikari,无需额外引入) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- Redis Lettuce -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 配置属性绑定 @ConfigurationProperties -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
✅ 调参核心准则(非常关键)
Hikari maximum-pool-size 不要超过数据库的 max_connections,MySQL 默认一般 151;大多数业务 10~20 足够,不是越大越快!连接多了会造成数据库锁竞争、上下文切换飙升。
Lettuce 是异步非阻塞,Redis 连接池不需要开很大,Lettuce 底层多路复用,很多人踩坑把 redis 连接池开几百完全没必要。
Tomcat 线程池、业务线程池、Hikari、Redis 池是四套独立池,不要混淆:
Tomcat:接收 HTTP 请求
Hikari:数据库连接
Lettuce pool:Redis 连接
bizTaskExecutor:自定义异步业务
拒绝策略:高并发场景不要用
CallerRunsPolicy(会把任务打回 Tomcat 线程,阻塞 web 请求);优先 AbortPolicy + 监控告警。
📌 监控配套建议(生产必加)
接入 Micrometer + Prometheus 监控:hikari、lettuce、线程池队列、活跃线程数
重点告警:Hikari 连接等待超时、连接泄露、线程池队列堆积、拒绝任务次数
本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
欢迎访问