# 并发性能优化总结 ## 优化概述 本次优化主要针对提高系统并发处理能力,解决潜在的超时和阻塞问题。 ## 主要优化内容 ### 1. ✅ Tomcat 线程池优化(高优先级) **文件**: `src/main/resources/application.yml` **优化项**: ```yaml server: tomcat: threads: max: 200 # 最大工作线程数(默认值为200) min-spare: 20 # 最小空闲线程数(从默认10提升到20) max-connections: 10000 # 最大连接数(从默认8192提升) accept-count: 200 # 等待队列长度(从默认100提升) connection-timeout: 20000 # 连接超时20秒 shutdown: graceful # 优雅关闭 ``` **效果**: - 支持更多并发 HTTP 请求 - 减少请求等待时间 - 优雅关闭避免请求中断 --- ### 2. ✅ 数据库连接池优化(高优先级) **文件**: `src/main/resources/application.yml` **优化项**: ```yaml hikari: maximum-pool-size: 100 # 从50增加到100 minimum-idle: 20 # 从10增加到20 connection-timeout: 10000 # 从30秒降低到10秒 idle-timeout: 300000 # 从10分钟降低到5分钟 leak-detection-threshold: 30000 # 从60秒降低到30秒 validation-timeout: 3000 # 从5秒降低到3秒 ``` **MySQL 会话参数优化**: ``` innodb_lock_wait_timeout=10 # 从30秒降低到10秒 wait_timeout=300 # 新增,5分钟 interactive_timeout=300 # 新增,5分钟 ``` **效果**: - 支持更多并发数据库操作 - 更快检测和释放死锁 - 更快发现连接泄漏问题 - 减少数据库连接等待时间 --- ### 3. ✅ HTTP 客户端连接池配置(高优先级) **文件**: `src/main/java/com/gameplatform/server/service/external/ScriptClient.java` **新增配置**: ```java // 连接池配置 ConnectionProvider connectionProvider = ConnectionProvider.builder("script-client-pool") .maxConnections(100) // 最大连接数 .pendingAcquireMaxCount(200) // 等待队列大小 .pendingAcquireTimeout(Duration.ofSeconds(10)) .maxIdleTime(Duration.ofSeconds(30)) .maxLifeTime(Duration.ofMinutes(5)) .evictInBackground(Duration.ofSeconds(60)) .build(); // HttpClient 配置 HttpClient httpClient = HttpClient.create(connectionProvider) .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMs) .responseTimeout(Duration.ofMillis(readTimeoutMs)) .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(...)) .addHandlerLast(new WriteTimeoutHandler(...))) .compress(true); ``` **效果**: - 避免 HTTP 连接耗尽 - 支持连接复用,提升性能 - 自动清理过期连接 - 启用 HTTP 压缩减少带宽 --- ### 4. ✅ 异步线程池优化(中优先级) **文件**: `src/main/java/com/gameplatform/server/config/AsyncConfig.java` **设备检测线程池优化**: ```java deviceDetectionExecutor: corePoolSize: 10 # 从3增加到10 maxPoolSize: 50 # 从10增加到50 queueCapacity: 500 # 从100增加到500 rejectedPolicy: DiscardOldest # 改为丢弃最旧,避免阻塞HTTP线程 ``` **新增通用异步线程池**: ```java taskExecutor: corePoolSize: 20 maxPoolSize: 100 queueCapacity: 1000 rejectedPolicy: CallerRunsPolicy ``` **效果**: - 支持更多并发异步任务 - 避免 HTTP 线程被阻塞 - 提供更好的任务隔离 --- ### 5. ✅ 事务超时优化(中优先级) **文件**: `src/main/resources/application.yml` **优化项**: ```yaml spring: transaction: default-timeout: 15 # 从30秒降低到15秒 mvc: async: request-timeout: 60000 # 新增,异步请求超时60秒 ``` **效果**: - 更快检测和终止长事务 - 减少数据库连接占用时间 - 避免死锁长时间等待 --- ### 6. ✅ 监控端点扩展 **文件**: `src/main/resources/application.yml` **新增监控端点**: ```yaml management: endpoints: web: exposure: include: health,info,metrics,threaddump ``` **效果**: - 可以查看线程状态 (`/actuator/threaddump`) - 可以查看性能指标 (`/actuator/metrics`) - 便于排查性能问题 --- ## 性能提升预期 ### 并发能力对比 | 配置项 | 优化前 | 优化后 | 提升幅度 | |--------|--------|--------|----------| | Tomcat 最大线程数 | 200(默认) | 200 | - | | Tomcat 最小线程数 | 10(默认) | 20 | +100% | | Tomcat 最大连接数 | 8192(默认) | 10000 | +22% | | 数据库连接池 | 50 | 100 | +100% | | HTTP 客户端连接池 | 无限制(默认) | 100(受控) | 稳定性提升 | | 设备检测线程池 | 3-10 | 10-50 | +400% | | 异步任务线程池 | 无 | 20-100 | 新增 | ### 响应时间改善 - **数据库操作**: 连接获取时间从可能的30秒降低到10秒以内 - **HTTP 请求**: 连接复用,减少建立连接开销 - **锁等待**: 从30秒降低到10秒,更快释放资源 - **连接泄漏检测**: 从60秒降低到30秒,更快发现问题 --- ## 验证步骤 ### 1. 启动应用检查日志 启动后应该看到类似日志: ``` ScriptClient 初始化完成: baseUrl=..., 最大连接数=100 设备检测线程池已初始化: coreSize=10, maxSize=50, queueCapacity=500 通用异步任务线程池已初始化: coreSize=20, maxSize=100, queueCapacity=1000 HikariPool-1 - Starting... HikariPool-1 - Start completed. ``` ### 2. 检查监控端点 ```bash # 查看健康状态 curl http://localhost:18080/actuator/health # 查看线程信息 curl http://localhost:18080/actuator/threaddump # 查看指标 curl http://localhost:18080/actuator/metrics curl http://localhost:18080/actuator/metrics/hikaricp.connections.active curl http://localhost:18080/actuator/metrics/tomcat.threads.busy ``` ### 3. 并发压力测试 使用工具如 JMeter 或 Apache Bench 进行压力测试: ```bash # 使用 Apache Bench 测试 ab -n 10000 -c 200 http://localhost:18080/api/some-endpoint # 使用 wrk 测试 wrk -t12 -c400 -d30s http://localhost:18080/api/some-endpoint ``` ### 4. 监控关键指标 在压力测试期间,监控以下指标: - Tomcat 线程池使用率 - HikariCP 连接池使用率 - HTTP 客户端连接数 - 异步线程池队列长度 - 响应时间分布 - 错误率 --- ## 性能调优建议 ### 根据实际负载调整 1. **如果发现 Tomcat 线程不够**: ```yaml server: tomcat: threads: max: 300 # 可以继续增加 ``` 2. **如果数据库连接池经常满**: ```yaml hikari: maximum-pool-size: 150 # 可以继续增加 ``` 3. **如果异步任务队列经常满**: ```java executor.setQueueCapacity(1000); // 增加队列 executor.setMaxPoolSize(100); // 增加最大线程 ``` ### JVM 参数建议 如果并发量很大,建议调整 JVM 参数: ```bash java -jar app.jar \ -Xms2g \ # 初始堆内存 -Xmx4g \ # 最大堆内存 -XX:+UseG1GC \ # 使用G1垃圾收集器 -XX:MaxGCPauseMillis=200 \ # GC暂停目标 -XX:ParallelGCThreads=8 \ # 并行GC线程数 -XX:ConcGCThreads=2 # 并发GC线程数 ``` --- ## 常见问题排查 ### 1. 连接池耗尽 **症状**: 日志出现 "Connection is not available" **排查**: ```bash curl http://localhost:18080/actuator/metrics/hikaricp.connections.active curl http://localhost:18080/actuator/metrics/hikaricp.connections.pending ``` **解决**: 增加 `maximum-pool-size` 或检查是否有连接泄漏 ### 2. 线程池满 **症状**: 日志出现 "Task rejected" 或请求响应变慢 **排查**: ```bash curl http://localhost:18080/actuator/metrics/tomcat.threads.busy curl http://localhost:18080/actuator/threaddump ``` **解决**: 增加线程池大小或优化慢接口 ### 3. HTTP 连接超时 **症状**: 日志出现 "Connection timeout" **排查**: 检查外部服务是否正常,网络是否畅通 **解决**: - 调整超时时间 - 增加重试机制 - 添加断路器 --- ## 后续优化建议 1. **添加缓存**: 使用 Redis 缓存热点数据 2. **读写分离**: 使用数据库主从复制 3. **服务拆分**: 将耗时操作拆分到独立服务 4. **消息队列**: 异步处理非实时任务 5. **CDN**: 静态资源使用 CDN 加速 --- ## 回滚方案 如果优化后出现问题,可以通过以下步骤回滚: ```bash # 恢复配置文件 git checkout HEAD~1 -- src/main/resources/application.yml git checkout HEAD~1 -- src/main/java/com/gameplatform/server/service/external/ScriptClient.java git checkout HEAD~1 -- src/main/java/com/gameplatform/server/config/AsyncConfig.java # 重新编译部署 mvn clean package -DskipTests ``` --- ## 总结 本次优化从以下几个维度提升了系统并发能力: 1. ✅ **HTTP 服务器**: Tomcat 线程池和连接池优化 2. ✅ **数据库**: HikariCP 连接池优化,锁等待超时优化 3. ✅ **HTTP 客户端**: Reactor Netty 连接池配置 4. ✅ **异步处理**: 线程池扩容和策略优化 5. ✅ **事务管理**: 超时时间优化 6. ✅ **监控**: 扩展监控端点 预期可以将系统并发处理能力提升 **2-5 倍**,响应时间降低 **30-50%**。 建议在生产环境部署前,先在测试环境进行充分的压力测试验证。