diff --git a/fund-common/src/main/java/com/fundplatform/common/config/TenantRoutingProperties.java b/fund-common/src/main/java/com/fundplatform/common/config/TenantRoutingProperties.java
index 3f3e459..3e5e514 100644
--- a/fund-common/src/main/java/com/fundplatform/common/config/TenantRoutingProperties.java
+++ b/fund-common/src/main/java/com/fundplatform/common/config/TenantRoutingProperties.java
@@ -3,24 +3,36 @@ package com.fundplatform.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
-import java.util.*;
+import java.util.Arrays;
+import java.util.List;
/**
* 多租户路由配置属性
*
- *
支持从 YAML 配置文件读取租户路由配置
+ * 租户路由基于 Nacos 服务实例的 metadata.tenant-group 元数据进行匹配
*
- * 配置示例:
+ * 工作原理:
+ *
+ * 1. 服务实例注册到 Nacos 时,在 metadata 中声明 tenant-group
+ * - 共享实例: tenant-group 为空或不存在
+ * - VIP 实例: tenant-group = "TENANT_VIP_001"
+ *
+ * 2. Gateway 从请求中提取租户组,负载均衡器匹配实例元数据
+ * - 请求 tenantGroup = "TENANT_VIP_001" → 路由到匹配的 VIP 实例
+ * - 无匹配实例 → 回退到共享实例
+ *
+ *
+ * 配置示例:
*
* tenant:
* routing:
* enabled: true
- * default-tenant-id: 1
- * services:
- * fund-sys:
- * vip-tenants:
- * - TENANT_VIP_001
- * fallback-to-shared: true
+ * tenant-header: X-Tenant-Id
+ * default-tenant-id: "1"
+ * fallback-to-shared: true
+ * shared-services:
+ * - fund-gateway
+ * - fund-report
*
*/
@Component
@@ -49,13 +61,8 @@ public class TenantRoutingProperties {
"fund-file"
);
- /** 租户服务配置映射 */
- private Map services = new HashMap<>();
-
- /** 租户服务配置(旧版兼容) */
- private Map tenantConfigs = new HashMap<>();
-
- // Getters and Setters
+ /** 是否回退到共享实例(当找不到租户专属实例时) */
+ private boolean fallbackToShared = true;
public boolean isEnabled() {
return enabled;
@@ -105,24 +112,19 @@ public class TenantRoutingProperties {
this.sharedServices = sharedServices;
}
- public Map getServices() {
- return services;
+ public boolean isFallbackToShared() {
+ return fallbackToShared;
}
- public void setServices(Map services) {
- this.services = services;
- }
-
- public Map getTenantConfigs() {
- return tenantConfigs;
- }
-
- public void setTenantConfigs(Map tenantConfigs) {
- this.tenantConfigs = tenantConfigs;
+ public void setFallbackToShared(boolean fallbackToShared) {
+ this.fallbackToShared = fallbackToShared;
}
/**
* 构建租户组名称
+ *
+ * @param tenantId 租户 ID
+ * @return 租户组名称,如 "TENANT_VIP_001"
*/
public String buildTenantGroup(String tenantId) {
if (tenantId == null || tenantId.isEmpty()) {
@@ -133,205 +135,11 @@ public class TenantRoutingProperties {
/**
* 判断是否为共享服务
+ *
+ * @param serviceName 服务名
+ * @return 是否为共享服务
*/
public boolean isSharedService(String serviceName) {
- return sharedServices.contains(serviceName);
- }
-
- /**
- * 获取服务的 VIP 租户列表
- */
- public List getVipTenants(String serviceName) {
- TenantServiceConfig config = services.get(serviceName);
- if (config != null && config.getVipTenants() != null) {
- return config.getVipTenants();
- }
- return Collections.emptyList();
- }
-
- /**
- * 判断租户是否为某个服务的 VIP 租户
- */
- public boolean isVipTenant(String serviceName, String tenantGroup) {
- if (tenantGroup == null || tenantGroup.isEmpty()) {
- return false;
- }
- List vipTenants = getVipTenants(serviceName);
- return vipTenants.contains(tenantGroup);
- }
-
- /**
- * 判断服务是否启用了共享实例回退
- */
- public boolean isFallbackToShared(String serviceName) {
- TenantServiceConfig config = services.get(serviceName);
- if (config != null) {
- return config.isFallbackToShared();
- }
- return true; // 默认启用回退
- }
-
- /**
- * 租户服务配置
- */
- public static class TenantServiceConfig {
- /** VIP 租户列表(优先路由到专属实例) */
- private List vipTenants = new ArrayList<>();
-
- /** 是否回退到共享实例 */
- private boolean fallbackToShared = true;
-
- /** 租户 ID */
- private String tenantId;
-
- /** 服务实例配置 */
- private Map instances = new HashMap<>();
-
- /** 数据库配置(一库一租户模式) */
- private DatabaseConfig database;
-
- // Getters and Setters
-
- public List getVipTenants() {
- return vipTenants;
- }
-
- public void setVipTenants(List vipTenants) {
- this.vipTenants = vipTenants != null ? vipTenants : new ArrayList<>();
- }
-
- public boolean isFallbackToShared() {
- return fallbackToShared;
- }
-
- public void setFallbackToShared(boolean fallbackToShared) {
- this.fallbackToShared = fallbackToShared;
- }
-
- public String getTenantId() {
- return tenantId;
- }
-
- public void setTenantId(String tenantId) {
- this.tenantId = tenantId;
- }
-
- public Map getInstances() {
- return instances;
- }
-
- public void setInstances(Map instances) {
- this.instances = instances;
- }
-
- public DatabaseConfig getDatabase() {
- return database;
- }
-
- public void setDatabase(DatabaseConfig database) {
- this.database = database;
- }
- }
-
- /**
- * 服务实例配置
- */
- public static class ServiceInstanceConfig {
- /** 服务名 */
- private String serviceName;
-
- /** 端口号 */
- private int port = 8080;
-
- /** 实例数(用于负载均衡) */
- private int replicas = 1;
-
- /** 权重(用于加权负载均衡) */
- private int weight = 1;
-
- // Getters and Setters
-
- public String getServiceName() {
- return serviceName;
- }
-
- public void setServiceName(String serviceName) {
- this.serviceName = serviceName;
- }
-
- public int getPort() {
- return port;
- }
-
- public void setPort(int port) {
- this.port = port;
- }
-
- public int getReplicas() {
- return replicas;
- }
-
- public void setReplicas(int replicas) {
- this.replicas = replicas;
- }
-
- public int getWeight() {
- return weight;
- }
-
- public void setWeight(int weight) {
- this.weight = weight;
- }
- }
-
- /**
- * 数据库配置(用于一库一租户)
- */
- public static class DatabaseConfig {
- /** JDBC URL */
- private String url;
-
- /** 用户名 */
- private String username;
-
- /** 密码 */
- private String password;
-
- /** 驱动类名 */
- private String driverClassName = "com.mysql.cj.jdbc.Driver";
-
- // Getters and Setters
-
- public String getUrl() {
- return url;
- }
-
- public void setUrl(String url) {
- this.url = url;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getDriverClassName() {
- return driverClassName;
- }
-
- public void setDriverClassName(String driverClassName) {
- this.driverClassName = driverClassName;
- }
+ return sharedServices != null && sharedServices.contains(serviceName);
}
}
diff --git a/fund-common/src/main/java/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.java b/fund-common/src/main/java/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.java
index 7548599..ff778f8 100644
--- a/fund-common/src/main/java/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.java
+++ b/fund-common/src/main/java/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.java
@@ -180,7 +180,7 @@ public class TenantAwareLoadBalancer implements ReactorServiceInstanceLoadBalanc
// 检查是否启用回退到共享实例
boolean fallbackEnabled = true;
if (routingProperties != null) {
- fallbackEnabled = routingProperties.isFallbackToShared(serviceId);
+ fallbackEnabled = routingProperties.isFallbackToShared();
}
if (!fallbackEnabled) {
diff --git a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$DatabaseConfig.class b/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$DatabaseConfig.class
deleted file mode 100644
index 2030c3a..0000000
Binary files a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$DatabaseConfig.class and /dev/null differ
diff --git a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$ServiceInstanceConfig.class b/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$ServiceInstanceConfig.class
deleted file mode 100644
index e3ca2f7..0000000
Binary files a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$ServiceInstanceConfig.class and /dev/null differ
diff --git a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$TenantServiceConfig.class b/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$TenantServiceConfig.class
deleted file mode 100644
index d995dd6..0000000
Binary files a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties$TenantServiceConfig.class and /dev/null differ
diff --git a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties.class b/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties.class
index b7e6ac5..354ff20 100644
Binary files a/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties.class and b/fund-common/target/classes/com/fundplatform/common/config/TenantRoutingProperties.class differ
diff --git a/fund-common/target/classes/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.class b/fund-common/target/classes/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.class
index 824d078..18c4901 100644
Binary files a/fund-common/target/classes/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.class and b/fund-common/target/classes/com/fundplatform/common/loadbalancer/TenantAwareLoadBalancer.class differ
diff --git a/fund-common/target/surefire-reports/TEST-com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.xml b/fund-common/target/surefire-reports/TEST-com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.xml
index 0e68515..9c897c6 100644
--- a/fund-common/target/surefire-reports/TEST-com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.xml
+++ b/fund-common/target/surefire-reports/TEST-com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.xml
@@ -1,5 +1,5 @@
-
+
@@ -13,7 +13,7 @@
-
+
@@ -29,7 +29,7 @@
-
+
@@ -56,17 +56,17 @@
-
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/fund-common/target/surefire-reports/com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.txt b/fund-common/target/surefire-reports/com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.txt
index 42d9b9d..b17f2d0 100644
--- a/fund-common/target/surefire-reports/com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.txt
+++ b/fund-common/target/surefire-reports/com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest.txt
@@ -1,4 +1,4 @@
-------------------------------------------------------------------------------
Test set: com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest
-------------------------------------------------------------------------------
-Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.567 s -- in com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest
+Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.310 s -- in com.fundplatform.common.loadbalancer.TenantAwareLoadBalancerTest
diff --git a/fund-gateway/src/main/resources/application.yml b/fund-gateway/src/main/resources/application.yml
index cee858a..cc5e417 100644
--- a/fund-gateway/src/main/resources/application.yml
+++ b/fund-gateway/src/main/resources/application.yml
@@ -128,7 +128,7 @@ logging:
org.springframework.cloud.gateway: DEBUG
com.fundplatform.common.loadbalancer: DEBUG
-# 多租户路由配置
+# 多租户路由配置(Gateway 全局配置)
tenant:
routing:
enabled: true
@@ -136,21 +136,10 @@ tenant:
tenant-group-header: X-Tenant-Group
group-separator: TENANT_
default-tenant-id: "1"
+ # 共享服务列表(不需要租户路由的服务)
shared-services:
- fund-gateway
- fund-report
- fund-file
- services:
- fund-sys:
- vip-tenants:
- - TENANT_VIP_001
- - TENANT_VIP_002
- fallback-to-shared: true
- fund-cust:
- vip-tenants:
- - TENANT_VIP_001
- fallback-to-shared: true
- fund-proj:
- vip-tenants:
- - TENANT_VIP_001
- fallback-to-shared: true
+ # 默认回退策略
+ fallback-to-shared: true
diff --git a/fund-gateway/target/classes/application.yml b/fund-gateway/target/classes/application.yml
index cee858a..cc5e417 100644
--- a/fund-gateway/target/classes/application.yml
+++ b/fund-gateway/target/classes/application.yml
@@ -128,7 +128,7 @@ logging:
org.springframework.cloud.gateway: DEBUG
com.fundplatform.common.loadbalancer: DEBUG
-# 多租户路由配置
+# 多租户路由配置(Gateway 全局配置)
tenant:
routing:
enabled: true
@@ -136,21 +136,10 @@ tenant:
tenant-group-header: X-Tenant-Group
group-separator: TENANT_
default-tenant-id: "1"
+ # 共享服务列表(不需要租户路由的服务)
shared-services:
- fund-gateway
- fund-report
- fund-file
- services:
- fund-sys:
- vip-tenants:
- - TENANT_VIP_001
- - TENANT_VIP_002
- fallback-to-shared: true
- fund-cust:
- vip-tenants:
- - TENANT_VIP_001
- fallback-to-shared: true
- fund-proj:
- vip-tenants:
- - TENANT_VIP_001
- fallback-to-shared: true
+ # 默认回退策略
+ fallback-to-shared: true
diff --git a/fund-sys/src/main/resources/application.yml b/fund-sys/src/main/resources/application.yml
index ab78c4e..73ec11a 100644
--- a/fund-sys/src/main/resources/application.yml
+++ b/fund-sys/src/main/resources/application.yml
@@ -76,22 +76,18 @@ logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
-# 多租户路由配置
+# 多租户路由配置(服务实例只需声明自己的租户组)
tenant:
routing:
enabled: true
tenant-header: X-Tenant-Id
tenant-group-header: X-Tenant-Group
- group-separator: TENANT_
default-tenant-id: "1"
+ # 共享服务列表
shared-services:
- fund-gateway
- fund-report
- fund-file
- services:
- fund-sys:
- vip-tenants:
- - TENANT_VIP_001
- - TENANT_VIP_002
- fallback-to-shared: true
+ # 回退到共享实例
+ fallback-to-shared: true
diff --git a/fund-sys/target/classes/application.yml b/fund-sys/target/classes/application.yml
index ab78c4e..73ec11a 100644
--- a/fund-sys/target/classes/application.yml
+++ b/fund-sys/target/classes/application.yml
@@ -76,22 +76,18 @@ logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
-# 多租户路由配置
+# 多租户路由配置(服务实例只需声明自己的租户组)
tenant:
routing:
enabled: true
tenant-header: X-Tenant-Id
tenant-group-header: X-Tenant-Group
- group-separator: TENANT_
default-tenant-id: "1"
+ # 共享服务列表
shared-services:
- fund-gateway
- fund-report
- fund-file
- services:
- fund-sys:
- vip-tenants:
- - TENANT_VIP_001
- - TENANT_VIP_002
- fallback-to-shared: true
+ # 回退到共享实例
+ fallback-to-shared: true
diff --git a/logs/fund-sys-shared-8100.log b/logs/fund-sys-shared-8100.log
index 4259cb1..715d6da 100644
--- a/logs/fund-sys-shared-8100.log
+++ b/logs/fund-sys-shared-8100.log
@@ -1102,3 +1102,21 @@ java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBea
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-02-19 21:16:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:16:06.991 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:16:06.991 [scheduling-1] [] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task
+java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBean.getActiveConnections()" because the return value of "com.zaxxer.hikari.HikariDataSource.getHikariPoolMXBean()" is null
+ at com.fundplatform.sys.config.HikariMonitorConfig.monitorHikariPool(HikariMonitorConfig.java:38)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
+ at io.micrometer.observation.Observation.observe(Observation.java:499)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
+ at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
+ at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
+ at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
+ at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
diff --git a/logs/fund-sys-tenant-vip001-8101.log b/logs/fund-sys-tenant-vip001-8101.log
index a31a855..32c1d24 100644
--- a/logs/fund-sys-tenant-vip001-8101.log
+++ b/logs/fund-sys-tenant-vip001-8101.log
@@ -1066,3 +1066,21 @@ java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBea
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-02-19 21:14:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:14:07.550 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:14:07.551 [scheduling-1] [] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task
+java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBean.getActiveConnections()" because the return value of "com.zaxxer.hikari.HikariDataSource.getHikariPoolMXBean()" is null
+ at com.fundplatform.sys.config.HikariMonitorConfig.monitorHikariPool(HikariMonitorConfig.java:38)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
+ at io.micrometer.observation.Observation.observe(Observation.java:499)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
+ at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
+ at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
+ at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
+ at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
diff --git a/logs/fund-sys/error.log b/logs/fund-sys/error.log
index b6f0c8f..8e96c1f 100644
--- a/logs/fund-sys/error.log
+++ b/logs/fund-sys/error.log
@@ -1438,3 +1438,35 @@ java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBea
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-02-19 21:14:07.551 [scheduling-1] [] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task
+java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBean.getActiveConnections()" because the return value of "com.zaxxer.hikari.HikariDataSource.getHikariPoolMXBean()" is null
+ at com.fundplatform.sys.config.HikariMonitorConfig.monitorHikariPool(HikariMonitorConfig.java:38)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
+ at io.micrometer.observation.Observation.observe(Observation.java:499)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
+ at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
+ at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
+ at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
+ at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
+2026-02-19 21:16:06.991 [scheduling-1] [] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task
+java.lang.NullPointerException: Cannot invoke "com.zaxxer.hikari.HikariPoolMXBean.getActiveConnections()" because the return value of "com.zaxxer.hikari.HikariDataSource.getHikariPoolMXBean()" is null
+ at com.fundplatform.sys.config.HikariMonitorConfig.monitorHikariPool(HikariMonitorConfig.java:38)
+ at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
+ at java.base/java.lang.reflect.Method.invoke(Method.java:580)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124)
+ at io.micrometer.observation.Observation.observe(Observation.java:499)
+ at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:124)
+ at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
+ at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
+ at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:358)
+ at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
+ at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
+ at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
+ at java.base/java.lang.Thread.run(Thread.java:1583)
diff --git a/logs/fund-sys/info.log b/logs/fund-sys/info.log
index bf83d99..369e7d4 100644
--- a/logs/fund-sys/info.log
+++ b/logs/fund-sys/info.log
@@ -324,3 +324,7 @@
2026-02-19 21:09:07.550 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
2026-02-19 21:11:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
2026-02-19 21:11:06.996 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:14:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:14:07.550 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:16:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:16:06.991 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool