From d5dff648c09b9cb64ebb85b055e7e3d40889736e Mon Sep 17 00:00:00 2001 From: tjq Date: Tue, 13 Aug 2024 00:59:52 +0800 Subject: [PATCH] feat: add LeakDetection to find h2's problem #912 --- .../tech/powerjob/common/PowerJobDKey.java | 5 ++++ .../powerjob/common/utils/DebugUtils.java | 30 +++++++++++++++++++ .../persistence/db/ConnectionFactory.java | 16 ++++++++++ 3 files changed, 51 insertions(+) create mode 100644 powerjob-common/src/main/java/tech/powerjob/common/utils/DebugUtils.java diff --git a/powerjob-common/src/main/java/tech/powerjob/common/PowerJobDKey.java b/powerjob-common/src/main/java/tech/powerjob/common/PowerJobDKey.java index cf9819a6..c7e987f3 100644 --- a/powerjob-common/src/main/java/tech/powerjob/common/PowerJobDKey.java +++ b/powerjob-common/src/main/java/tech/powerjob/common/PowerJobDKey.java @@ -64,4 +64,9 @@ public class PowerJobDKey { public static final String WORKER_RUNTIME_SWAP_TASK_SCHEDULE_INTERVAL_MS = "powerjob.worker.swap.scan-interval"; + /** + * DebugLevel + */ + public static final String DEBUG_LEVEL = "powerjob.debug.level"; + } diff --git a/powerjob-common/src/main/java/tech/powerjob/common/utils/DebugUtils.java b/powerjob-common/src/main/java/tech/powerjob/common/utils/DebugUtils.java new file mode 100644 index 00000000..ee3fd7a2 --- /dev/null +++ b/powerjob-common/src/main/java/tech/powerjob/common/utils/DebugUtils.java @@ -0,0 +1,30 @@ +package tech.powerjob.common.utils; + +import org.apache.commons.lang3.StringUtils; +import tech.powerjob.common.PowerJobDKey; + +/** + * Debug 工具 + * + * @author tjq + * @since 2024/8/13 + */ +public class DebugUtils { + + private static Boolean debugMode; + + /** + * 判断当前是否处在 PowerJob 的 Debug 模式 + * @return inDebugMode + */ + public static boolean inDebugMode() { + + if (debugMode != null) { + return debugMode; + } + + String debug = PropertyUtils.readProperty(PowerJobDKey.DEBUG_LEVEL, null); + debugMode = StringUtils.isNotEmpty(debug); + return debugMode; + } +} diff --git a/powerjob-worker/src/main/java/tech/powerjob/worker/persistence/db/ConnectionFactory.java b/powerjob-worker/src/main/java/tech/powerjob/worker/persistence/db/ConnectionFactory.java index 1e8f95b7..21dbb2ee 100644 --- a/powerjob-worker/src/main/java/tech/powerjob/worker/persistence/db/ConnectionFactory.java +++ b/powerjob-worker/src/main/java/tech/powerjob/worker/persistence/db/ConnectionFactory.java @@ -1,6 +1,7 @@ package tech.powerjob.worker.persistence.db; import tech.powerjob.common.utils.CommonUtils; +import tech.powerjob.common.utils.DebugUtils; import tech.powerjob.common.utils.JavaUtils; import tech.powerjob.worker.common.constants.StoreStrategy; import com.zaxxer.hikari.HikariConfig; @@ -36,6 +37,11 @@ public class ConnectionFactory { public synchronized void initDatasource(StoreStrategy strategy) { + if (dataSource != null) { + log.warn("[PowerDatasource] ConnectionFactory already initialized!"); + return; + } + // H2 兼容性问题较多,前置输出版本方便排查 log.info("[PowerDatasource] H2 database version: {}", JavaUtils.determinePackageVersion(Driver.class)); @@ -46,10 +52,20 @@ public class ConnectionFactory { config.setDriverClassName(Driver.class.getName()); config.setJdbcUrl(strategy == StoreStrategy.DISK ? DISK_JDBC_URL : MEMORY_JDBC_URL); config.setAutoCommit(true); + // 连接空闲超过此时间后将被回收,单位为毫秒 + config.setIdleTimeout(300000); // 池中最小空闲连接数量 config.setMinimumIdle(2); // 池中最大连接数量 config.setMaximumPoolSize(32); + // 使用线程安全的连接检查机制 + config.setConnectionTestQuery("SELECT 1"); + + // 检测连接泄漏的阈值,单位为毫秒 + if (DebugUtils.inDebugMode()) { + config.setLeakDetectionThreshold(10000); + } + dataSource = new HikariDataSource(config); log.info("[PowerDatasource] init h2 datasource successfully, use url: {}", config.getJdbcUrl());