feat: 优化异步线程池配置,增加设备检测和通用任务线程池的核心与最大线程数,提升并发处理能力;更新数据库连接池配置,增强连接管理和性能

This commit is contained in:
zyh
2025-10-03 11:35:23 +08:00
parent 19a5fd715f
commit b60a5717c6
6 changed files with 1056 additions and 24 deletions

View File

@@ -22,25 +22,27 @@ public class AsyncConfig {
/**
* 设备检测专用线程池
* 避免阻塞HTTP请求处理线程
* 优化配置以支持更高并发
*/
@Bean(name = "deviceDetectionExecutor")
public Executor deviceDetectionExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数:根据设备数量调整建议2-4个
executor.setCorePoolSize(3);
// 核心线程数:增加以处理更多并发任务
executor.setCorePoolSize(10);
// 最大线程数:高峰时可扩展
executor.setMaxPoolSize(10);
// 最大线程数:高峰时可扩展到更多
executor.setMaxPoolSize(50);
// 队列容量:允许排队的任务
executor.setQueueCapacity(100);
// 队列容量:增加队列以缓冲更多任务
executor.setQueueCapacity(500);
// 线程名称前缀,方便日志追踪
executor.setThreadNamePrefix("DeviceDetect-");
// 拒绝策略:队列满时由调用线程执行,确保任务不丢失
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 拒绝策略:使用丢弃最旧策略避免阻塞HTTP线程
// 注意:如果任务很重要,建议使用 AbortPolicy 并添加监控告警
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
// 线程空闲时间(秒)
executor.setKeepAliveSeconds(60);
@@ -56,7 +58,50 @@ public class AsyncConfig {
executor.initialize();
log.info("设备检测线程池已初始化: coreSize={}, maxSize={}, queueCapacity={}",
log.info("设备检测线程池已初始化: coreSize={}, maxSize={}, queueCapacity={}, rejectedPolicy=DiscardOldest",
executor.getCorePoolSize(), executor.getMaxPoolSize(), executor.getQueueCapacity());
return executor;
}
/**
* 通用异步任务线程池
* 用于其他异步操作
*/
@Bean(name = "taskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(20);
// 最大线程数
executor.setMaxPoolSize(100);
// 队列容量
executor.setQueueCapacity(1000);
// 线程名称前缀
executor.setThreadNamePrefix("AsyncTask-");
// 拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程空闲时间
executor.setKeepAliveSeconds(60);
// 允许核心线程超时
executor.setAllowCoreThreadTimeOut(true);
// 等待任务完成后再关闭
executor.setWaitForTasksToCompleteOnShutdown(true);
// 关闭等待时间
executor.setAwaitTerminationSeconds(60);
executor.initialize();
log.info("通用异步任务线程池已初始化: coreSize={}, maxSize={}, queueCapacity={}",
executor.getCorePoolSize(), executor.getMaxPoolSize(), executor.getQueueCapacity());
return executor;

View File

@@ -5,19 +5,26 @@ import com.gameplatform.server.model.dto.device.DeviceStatusResponse;
import com.gameplatform.server.model.entity.log.ScriptOperationLog;
import com.gameplatform.server.service.device.DeviceStatusService;
import com.gameplatform.server.service.log.ScriptOperationLogService;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
import reactor.util.retry.Retry;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
@Service
public class ScriptClient {
@@ -47,16 +54,36 @@ public class ScriptClient {
this.deviceStatusService = deviceStatusService;
this.eventPublisher = eventPublisher;
this.operationLogService = operationLogService;
// 配置连接池 - 提高并发性能
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(readTimeoutMs, TimeUnit.MILLISECONDS))
.addHandlerLast(new WriteTimeoutHandler(connectTimeoutMs, TimeUnit.MILLISECONDS)))
.compress(true); // 启用压缩
this.webClient = WebClient.builder()
.baseUrl(baseUrl)
.clientConnector(new ReactorClientHttpConnector(httpClient))
.exchangeStrategies(ExchangeStrategies.builder()
.codecs(cfg -> cfg.defaultCodecs().maxInMemorySize(2 * 1024 * 1024))
.build())
.build();
if (log.isDebugEnabled()) {
log.debug("ScriptClient initialized baseUrl={}, apiBaseUrl={}, connectTimeoutMs={}, readTimeoutMs={}",
this.baseUrl, this.apiBaseUrl, connectTimeoutMs, readTimeoutMs);
}
log.info("ScriptClient 初始化完成: baseUrl={}, apiBaseUrl={}, 连接超时={}ms, 读取超时={}ms, 最大连接数=100",
this.baseUrl, this.apiBaseUrl, connectTimeoutMs, readTimeoutMs);
}
public Mono<byte[]> getQrPng(String path) {

View File

@@ -3,18 +3,18 @@ spring:
name: gameplatform-server
datasource:
url: jdbc:mysql://192.140.164.137:3306/login_task_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&sessionVariables=innodb_lock_wait_timeout=30
url: jdbc:mysql://192.140.164.137:3306/login_task_db?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&sessionVariables=innodb_lock_wait_timeout=10,wait_timeout=300,interactive_timeout=300
username: login_task_db
password: 3MaXfeWJ4d6cGMrL
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 50
minimum-idle: 10
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
leak-detection-threshold: 60000
validation-timeout: 5000
maximum-pool-size: 100 # 增加最大连接数从50到100
minimum-idle: 20 # 增加最小空闲连接从10到20
connection-timeout: 10000 # 降低连接获取超时从30秒到10秒
idle-timeout: 300000 # 空闲连接超时5分钟从10分钟降低
max-lifetime: 1800000 # 连接最大存活30分钟
leak-detection-threshold: 30000 # 连接泄漏检测30秒从60秒降低
validation-timeout: 3000 # 连接验证超时3秒从5秒降低
connection-test-query: SELECT 1
# 连接池健康监控和自动重连
initialization-fail-timeout: 1
@@ -26,8 +26,12 @@ spring:
poll:
size: 4
transaction:
default-timeout: 30
default-timeout: 15 # 降低默认事务超时从30秒到15秒
mvc:
async:
request-timeout: 60000 # 异步请求超时60秒
lifecycle:
timeout-per-shutdown-phase: 30s # 关闭超时30秒
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
type-aliases-package: com.gameplatform.server.model.entity
@@ -43,12 +47,22 @@ mybatis-plus:
server:
port: 18080
# Tomcat 线程池配置 - 提高并发处理能力
tomcat:
threads:
max: 200 # 最大工作线程数默认200
min-spare: 20 # 最小空闲线程数默认10
max-connections: 10000 # 最大连接数默认8192
accept-count: 200 # 等待队列长度默认100
connection-timeout: 20000 # 连接超时20秒
shutdown: graceful # 优雅关闭
management:
endpoints:
web:
exposure:
include: health,info
include: health,info,metrics,threaddump
logging:
level: