Spring Boot 高并发优化终极指南,涵盖线程模型、JVM 调优、数据库访问、缓存策略等 15+ 核心模块
一、线程模型深度调优(核心瓶颈突破)
1. Tomcat 线程池原子级配置
server:
tomcat:
# 核心公式:maxThreads = (CPU核心数 * 2) + 磁盘数(SSD=1, HDD=0)
max-threads: 500 # 生产环境推荐值(默认200是性能陷阱)
min-spare-threads: 100 # 避免突发流量冷启动延迟
accept-count: 1000 # 等待队列容量(Linux默认128会丢包)
connection-timeout: 3000ms # 快速释放无效连接
max-connections: 10000 # 最大连接数(需与ulimit -n匹配)
keep-alive-timeout: 15000ms # 长连接超时(减少TCP握手)
max-keep-alive-requests: 100 # 单连接最大请求数(防连接独占)
调优依据:
- netstat -ant | grep ESTABLISHED 监控连接状态
- ss -s 检查TCP队列溢出(overflowed指标)
2. 异步任务线程池隔离策略
@Configuration
public class ExecutorConfig {
// CPU密集型任务(计算/加密)
@Bean("cpuExecutor")
public Executor cpuTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
executor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
executor.setQueueCapacity(0); // 无队列,避免任务堆积
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
return executor;
}
// IO密集型任务(网络请求/DB操作)
@Bean("ioExecutor")
public Executor ioTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(50);
executor.setMaxPoolSize(200);
executor.setQueueCapacity(1000);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("IO-Async-");
// 关键:线程保活时间(避免频繁创建销毁)
executor.setKeepAliveSeconds(300);
return executor;
}
}
监控指标:
# 查看线程池状态
jstack <pid> | grep "IO-Async" -A 10
# 输出示例:
"IO-Async-1" #32 daemon prio=5 os_prio=0 tid=0x00007f9b3828e000 nid=0x6d runnable [0x00007f9b2f7f1000]
二、JVM 层终极调参(G1GC 深度优化)
1. 内存分配策略
# JDK17+ 推荐配置
java -jar app.jar \
-Xms8g -Xmx8g \ # 堆内存固定(避免动态扩容)
-XX:MaxMetaspaceSize=512m \ # 元空间上限(防OOM)
-XX:ReservedCodeCacheSize=256m \ # JIT代码缓存
-XX:+UseG1GC \ # G1垃圾回收器
-XX:MaxGCPauseMillis=150 \ # 目标暂停时间(毫秒)
-XX:InitiatingHeapOccupancyPercent=35 \ # 早触发混合GC
-XX:ConcGCThreads=4 \ # 并发GC线程数(CPU核心数/4)
-XX:ParallelGCThreads=12 \ # 并行GC线程数(CPU核心数*0.75)
-XX:G1HeapRegionSize=4m \ # Region大小(大内存机器设4-8M)
-XX:+PerfDisableSharedMem \ # 禁用共享内存(避免JVM停顿)
-XX:+HeapDumpOnOutOfMemoryError \ # OOM时自动Dump
-XX:HeapDumpPath=/opt/dumps # Dump文件路径
2. GC 日志分析技巧
# 启用详细GC日志
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/opt/logs/gc.log
# 关键指标解析:
[GC pause (G1 Evacuation Pause) (young), 0.0231458 secs]
[Parallel Time: 21.5 ms, GC Workers: 8]
[Ext Root Scanning: 1.5 ms]
[Update RS (Remembered Sets): 0.2 ms]
[Processed Buffers: 300]
[Scan RS: 0.1 ms]
[Code Root Scanning: 0.0 ms]
[Object Copy: 19.5 ms]
[Termination: 0.1 ms]
[GC Worker Other: 0.5 ms]
[GC Worker Total: 22.0 ms]
优化方向:
- Object Copy 时间过长 → 增加 -XX:G1NewSizePercent
- Update RS 时间过长 → 增加 -XX:G1ConcRefinementThreads
三、缓存策略原子级优化
1. 三级缓存架构实现
@Service
public class ProductService {
// L1: Caffeine本地缓存(纳秒级)
private final Cache<Long, Product> l1Cache = Caffeine.newBuilder()
.maximumSize(10_000)
.expireAfterWrite(30, TimeUnit.SECONDS)
.recordStats() // 开启命中率统计
.build();
// L2: Redis分布式缓存
@Value("${cache.key.product}")
private String productKey;
// L3: 数据库
@Autowired
private ProductRepository repository;
public Product getProduct(Long id) {
// 1. 查L1缓存
Product product = l1Cache.getIfPresent(id);
if (product != null) return product;
// 2. 查L2缓存(Redis)
String redisKey = productKey + id;
product = redisTemplate.opsForValue().get(redisKey);
if (product != null) {
l1Cache.put(id, product); // 回填L1
return product;
}
// 3. 查数据库
product = repository.findById(id).orElseThrow();
// 4. 异步回填缓存
CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(redisKey, product, 5, TimeUnit.MINUTES);
l1Cache.put(id, product);
}, ioTaskExecutor);
return product;
}
}
2. 缓存穿透/雪崩防护
// 布隆过滤器 + 空值缓存
@Bean
public BloomFilter<Long> productBloomFilter() {
return BloomFilter.create(Funnels.longFunnel(), 1000000, 0.01);
}
public Product getProductSafe(Long id) {
// 布隆过滤器拦截
if (!bloomFilter.mightContain(id)) return null;
// 查缓存(含空值)
Product product = cache.get(id, key -> {
Product p = repository.findById(id).orElse(null);
if (p == null) {
// 缓存空对象(防穿透)
return Product.EMPTY;
}
return p;
});
return (product == Product.EMPTY) ? null : product;
}
四、数据库访问极致优化
1. 连接池死亡参数配置
spring:
datasource:
hikari:
pool-name: HikariCP-Master
maximum-pool-size: 20 # 公式: (core_count * 2) + disk_count
minimum-idle: 10
connection-timeout: 2000 # 必须 < 3s
max-lifetime: 1800000 # 30分钟(避免连接僵死)
idle-timeout: 600000 # 10分钟
leak-detection-threshold: 5000 # 连接泄漏检测(毫秒)
connection-test-query: SELECT 1 FROM DUAL # MySQL需设置
2. 分页查询深度优化方案
/* 传统分页(性能灾难)*/
SELECT * FROM orders ORDER BY create_time DESC LIMIT 1000000, 20;
/* 优化方案1:游标分页 */
SELECT * FROM orders
WHERE id > ? /* 上次查询的最大ID */
ORDER BY id LIMIT 20;
/* 优化方案2:覆盖索引 */
SELECT * FROM orders
INNER JOIN (
SELECT id FROM orders
ORDER BY create_time DESC
LIMIT 1000000, 20
) AS tmp USING(id);
3. 批量写入性能提升
// MyBatis 批量插入
@Insert("<script>" +
"INSERT INTO user (name,age) VALUES " +
"<foreach collection='list' item='item' separator=','>" +
"(#{item.name}, #{item.age})" +
"</foreach>" +
"</script>")
void batchInsert(@Param("list") List<User> users);
// JPA 批量配置
spring:
jpa:
properties:
hibernate:
jdbc:
batch_size: 500 # 批处理大小
order_inserts: true
order_updates: true
五、网络通信层优化
1. HTTP 连接池配置
# 使用Apache HttpClient
httpclient:
max-total: 200 # 最大连接数
default-max-per-route: 50 # 单路由最大连接
connect-timeout: 3000 # 连接超时
socket-timeout: 5000 # 数据传输超时
connection-request-timeout: 1000 # 获取连接超时
2. Keep-Alive 策略优化
@Bean
public HttpClient httpClient() {
return HttpClientBuilder.create()
.setConnectionManager(new PoolingHttpClientConnectionManager())
.setKeepAliveStrategy((response, context) -> 30000) // 30秒保活
.build();
}
六、限流熔断与降级策略
1. Sentinel 集群流控
// 集群流控规则
FlowRule rule = new FlowRule("queryProduct")
.setGrade(RuleConstant.FLOW_GRADE_QPS)
.setCount(1000) // 单机阈值
.setClusterMode(true) // 集群模式
.setClusterConfig(new ClusterFlowConfig()
.setFlowId(123) // 规则ID
.setThresholdType(ClusterRuleConstant.FLOW_THRESHOLD_GLOBAL)
);
FlowRuleManager.loadRules(Collections.singletonList(rule));
2. 熔断降级策略
@SentinelResource(value = "getProduct",
fallback = "getProductFallback",
blockHandler = "blockHandler",
exceptionsToIgnore = {IllegalArgumentException.class})
public Product getProduct(Long id) {
// 业务逻辑
}
// 熔断降级处理
public Product getProductFallback(Long id, Throwable ex) {
return ProductCache.get(id); // 返回缓存数据
}
七、压测实战与指标分析
1. JMeter 压测脚本关键配置
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="高并发场景" enabled="true">
<intProp name="ThreadGroup.num_threads">1000</intProp> <!-- 并发线程数 -->
<intProp name="ThreadGroup.ramp_time">60</intProp> <!-- 启动时间(秒) -->
<longProp name="ThreadGroup.duration">300</longProp> <!-- 持续时间 -->
</ThreadGroup>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="/product/{id}">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments">
<collectionProp name="Arguments.arguments">
<elementProp name="id" elementType="HTTPArgument">
<stringProp name="Argument.value">${__Random(1,10000)}</stringProp>
</elementProp>
</collectionProp>
</elementProp>
</HTTPSamplerProxy>
2. 关键性能指标看板
指标 | 健康阈值 | 异常处理方案 |
---|---|---|
QPS | ≤最大承载80% | 扩容/限流/降级 |
TP99响应时间 | <500ms | 优化慢查询/增加缓存 |
错误率 | <0.1% | 熔断/快速失败 |
CPU使用率 | <70% | 优化算法/扩容 |
GC暂停时间 | <200ms | JVM调优/升级GC算法 |
连接池等待线程数 | <10 | 增大连接池/优化SQL |
八、Spring Boot 3 性能王炸特性
1. 虚拟线程(Loom Project)
spring:
threads:
virtual:
enabled: true # 启用虚拟线程
executor:
core-pool-size: 1000 # 虚拟线程池大小
效果:
- 万级并发下内存占用减少 90%
- 吞吐量提升 300%
- 上下文切换成本降低 100 倍
2. 预编译优化(AOT)
# 启用Spring AOT预编译
spring-boot:build-image -Pnative
效果:
- 启动时间从 3.2s → 0.15s
- 内存占用减少 40%
九、生产环境诊断工具箱
1. Arthas 在线诊断
# 查看方法调用拓扑
trace com.example.service.*Service '*' -n 5
# 监控线程池状态
watch java.util.concurrent.ThreadPoolExecutor '{queue.size, activeCount}'
# 定位CPU热点
profiler start --event cpu --interval 10000000
2. Async Profiler 火焰图
# 生成CPU火焰图
./profiler.sh -d 60 -f flamegraph.html <pid>
十、千万级流量架构优化案例
电商大促场景优化效果
优化项 | 优化前 | 优化后 | 提升幅度 |
---|---|---|---|
平均响应时间 | 420ms | 68ms | 517% |
最大吞吐量(QPS) | 8,500 | 42,000 | 394% |
GC暂停时间 | 1.2s | 85ms | 93% |
订单创建延迟 | 350ms | 45ms | 677% |
错误率 | 1.8% | 0.03% | 98% |
核心优化点:
- Tomcat 线程池调优(maxThreads=800)
- G1GC 参数精细化(MaxGCPauseMillis=100)
- Redis 分片集群 + 本地缓存
- 分库分表 + 读写分离
- Sentinel 集群流控
十一、调优操作清单
- 线程池配置检查
curl http://localhost:8080/actuator/metrics/tomcat.threads.busy?tag=name:http-nio-8080
- GC日志分析
grep "Allocation Failure" gc.log | wc -l # 检查GC触发频率
- 慢SQL定位
# MySQL开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.1; # 100毫秒
- 网络连接监控
ss -s | grep "TCP:" # 查看TCP连接状态