feat: 优化异步线程池配置,增加设备检测和通用任务线程池的核心与最大线程数,提升并发处理能力;更新数据库连接池配置,增强连接管理和性能
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user