diff --git a/docker-compose.yml b/docker-compose.yml
index ca64613..5b5eac5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -184,8 +184,7 @@ services:
REDIS_HOST: redis
REDIS_PORT: 6379
JAVA_OPTS: -Xms256m -Xmx512m
- # 租户元数据 - 共享实例(无特定租户组,所有租户可用)
- TENANT_ID: "1"
+ # 租户组 - 共享实例(空值,所有租户可用)
TENANT_GROUP: ""
ports:
- "8100:8100"
@@ -228,8 +227,7 @@ services:
REDIS_HOST: redis
REDIS_PORT: 6379
JAVA_OPTS: -Xms256m -Xmx512m
- # 租户元数据 - VIP_001 专属实例
- TENANT_ID: "1001"
+ # 租户组 - VIP_001 专属实例
TENANT_GROUP: "TENANT_VIP_001"
ports:
- "8101:8101"
@@ -272,8 +270,7 @@ services:
# REDIS_HOST: redis
# REDIS_PORT: 6379
# JAVA_OPTS: -Xms256m -Xmx512m
- # # 租户元数据 - VIP_002 专属实例
- # TENANT_ID: "1002"
+ # # 租户组 - VIP_002 专属实例
# TENANT_GROUP: "TENANT_VIP_002"
# ports:
# - "8102:8102"
diff --git a/fund-common/src/main/java/com/fundplatform/common/nacos/NacosMetadataConfig.java b/fund-common/src/main/java/com/fundplatform/common/nacos/NacosMetadataConfig.java
index 4c0a208..aca6d9f 100644
--- a/fund-common/src/main/java/com/fundplatform/common/nacos/NacosMetadataConfig.java
+++ b/fund-common/src/main/java/com/fundplatform/common/nacos/NacosMetadataConfig.java
@@ -8,19 +8,27 @@ import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.context.annotation.Configuration;
import jakarta.annotation.PostConstruct;
-import java.util.HashMap;
import java.util.Map;
/**
* Nacos 服务注册元数据配置
*
- *
服务启动时自动注册租户标签到 Nacos,支持租户感知的负载均衡
+ * 服务启动时自动注册租户组标签到 Nacos,支持租户感知的负载均衡
*
- * 支持两种配置方式:
- *
- * - 环境变量:TENANT_ID, TENANT_GROUP(Docker 环境推荐)
- * - 配置文件:spring.cloud.nacos.discovery.metadata.tenant-id/tenant-group
- *
+ * 租户组配置规则:
+ *
+ * 共享实例: tenant-group 为空(或不配置)→ 所有租户都可使用
+ * VIP实例: tenant-group = "TENANT_VIP_001" → 仅该租户组可用
+ *
+ *
+ * 配置方式:
+ *
+ * # 方式1: 环境变量(Docker/K8s 推荐)
+ * TENANT_GROUP=TENANT_VIP_001
+ *
+ * # 方式2: 配置文件
+ * spring.cloud.nacos.discovery.metadata.tenant-group=TENANT_VIP_001
+ *
*/
@Configuration
@ConditionalOnProperty(name = "tenant.routing.enabled", havingValue = "true", matchIfMissing = true)
@@ -32,73 +40,37 @@ public class NacosMetadataConfig {
private String applicationName;
/**
- * 租户 ID,优先级:环境变量 > 配置文件 > 默认值
- */
- @Value("${TENANT_ID:${spring.cloud.nacos.discovery.metadata.tenant-id:1}}")
- private String tenantId;
-
- /**
- * 租户组,优先级:环境变量 > 配置文件 > 自动生成
+ * 租户组,优先级:环境变量 > 配置文件
* 为空表示共享实例,供所有租户使用
*/
@Value("${TENANT_GROUP:${spring.cloud.nacos.discovery.metadata.tenant-group:}}")
private String tenantGroup;
- /**
- * Nacos Registration Bean,用于动态添加元数据
- */
private final Registration registration;
public NacosMetadataConfig(Registration registration) {
this.registration = registration;
}
- /**
- * 初始化 Nacos 元数据
- */
@PostConstruct
public void init() {
- logger.info("[Nacos Metadata] 应用名:{}", applicationName);
- logger.info("[Nacos Metadata] 租户 ID: {}, 租户组:{}", tenantId, tenantGroup);
-
- // 动态添加租户元数据到服务注册信息
if (registration != null && registration.getMetadata() != null) {
Map metadata = registration.getMetadata();
- // 添加租户 ID
- if (tenantId != null && !tenantId.isEmpty()) {
- metadata.put("tenant-id", tenantId);
- }
-
- // 添加租户组(VIP 专属实例才有值,共享实例为空)
+ // 添加租户组元数据
if (tenantGroup != null && !tenantGroup.isEmpty()) {
metadata.put("tenant-group", tenantGroup);
- logger.info("[Nacos Metadata] 注册为 VIP 专属实例,租户组:{}", tenantGroup);
+ logger.info("[Nacos] {} 注册为 VIP 专属实例,租户组:{}", applicationName, tenantGroup);
} else {
- logger.info("[Nacos Metadata] 注册为共享实例,供所有租户使用");
+ logger.info("[Nacos] {} 注册为共享实例,供所有租户使用", applicationName);
}
-
- logger.info("[Nacos Metadata] 服务元数据:{}", metadata);
}
}
- /**
- * 获取当前租户 ID
- */
- public String getTenantId() {
- return tenantId;
- }
-
- /**
- * 获取当前租户组
- */
public String getTenantGroup() {
return tenantGroup;
}
- /**
- * 判断是否为 VIP 专属实例
- */
public boolean isVipInstance() {
return tenantGroup != null && !tenantGroup.isEmpty();
}
diff --git a/fund-common/target/classes/com/fundplatform/common/nacos/NacosMetadataConfig.class b/fund-common/target/classes/com/fundplatform/common/nacos/NacosMetadataConfig.class
index a9c6cf2..8a993c0 100644
Binary files a/fund-common/target/classes/com/fundplatform/common/nacos/NacosMetadataConfig.class and b/fund-common/target/classes/com/fundplatform/common/nacos/NacosMetadataConfig.class differ
diff --git a/fund-sys/src/main/resources/application.yml b/fund-sys/src/main/resources/application.yml
index 73ec11a..c38e6e5 100644
--- a/fund-sys/src/main/resources/application.yml
+++ b/fund-sys/src/main/resources/application.yml
@@ -13,10 +13,10 @@ spring:
group: DEFAULT_GROUP
username: nacos
password: nacos
- # 租户元数据(一库一租户模式时配置)
+ # 租户路由元数据
+ # tenant-group: 空值=共享实例,有值=VIP专属实例
metadata:
- tenant-id: ${TENANT_ID:1}
- tenant-group: TENANT_${TENANT_ID:DEFAULT}
+ tenant-group: ${TENANT_GROUP:}
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
diff --git a/fund-sys/target/classes/application.yml b/fund-sys/target/classes/application.yml
index 73ec11a..c38e6e5 100644
--- a/fund-sys/target/classes/application.yml
+++ b/fund-sys/target/classes/application.yml
@@ -13,10 +13,10 @@ spring:
group: DEFAULT_GROUP
username: nacos
password: nacos
- # 租户元数据(一库一租户模式时配置)
+ # 租户路由元数据
+ # tenant-group: 空值=共享实例,有值=VIP专属实例
metadata:
- tenant-id: ${TENANT_ID:1}
- tenant-group: TENANT_${TENANT_ID:DEFAULT}
+ tenant-group: ${TENANT_GROUP:}
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
diff --git a/logs/fund-sys-shared-8100.log b/logs/fund-sys-shared-8100.log
index 715d6da..56db073 100644
--- a/logs/fund-sys-shared-8100.log
+++ b/logs/fund-sys-shared-8100.log
@@ -1120,3 +1120,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:21:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:21:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:21:06.989 [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 32c1d24..a21e5d3 100644
--- a/logs/fund-sys-tenant-vip001-8101.log
+++ b/logs/fund-sys-tenant-vip001-8101.log
@@ -1084,3 +1084,39 @@ 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:19:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:19:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:19:07.541 [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:24:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:24:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:24:07.541 [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 8e96c1f..97aa294 100644
--- a/logs/fund-sys/error.log
+++ b/logs/fund-sys/error.log
@@ -1470,3 +1470,51 @@ 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:19:07.541 [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:21:06.989 [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:24:07.541 [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 369e7d4..4362c22 100644
--- a/logs/fund-sys/info.log
+++ b/logs/fund-sys/info.log
@@ -328,3 +328,9 @@
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
+2026-02-19 21:19:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:19:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:21:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:21:06.988 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool
+2026-02-19 21:24:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - === HikariCP 连接池状态 ===
+2026-02-19 21:24:07.541 [scheduling-1] [] INFO com.fundplatform.sys.config.HikariMonitorConfig - 连接池名称: FundSysHikariPool