feat: 服务资源配置文件增加多租户混合模式负载均衡配置

## application-docker.yml 更新

### fund-sys
- Nacos 元数据配置:tenant-id, tenant-group
- 租户路由配置:启用租户感知负载均衡
- VIP 租户列表定义
- 监控标签:tenant_id, tenant_group, instance_type
- 日志格式:增加 tenantId MDC

### fund-gateway
- 全局跨域配置
- 多租户路由配置(所有服务的VIP租户列表)
- 监控和日志增强

## TenantRoutingProperties 更新
- 添加 @ConfigurationProperties 支持 YAML 配置绑定
- 新增 vip-tenants 列表属性
- 新增 fallback-to-shared 回退策略属性
- 新增 getVipTenants(), isVipTenant(), isFallbackToShared() 方法
This commit is contained in:
zhangjf 2026-02-19 20:45:03 +08:00
parent 5843cc050e
commit 2c0f2f8952
3 changed files with 196 additions and 21 deletions

View File

@ -3,14 +3,32 @@ package com.fundplatform.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.*;
/**
* 多租户路由配置属性
*
* <p>支持从 YAML 配置文件读取租户路由配置</p>
*
* <p>配置示例</p>
* <pre>
* tenant:
* routing:
* enabled: true
* default-tenant-id: 1
* services:
* fund-sys:
* vip-tenants:
* - TENANT_VIP_001
* fallback-to-shared: true
* </pre>
*/
@Component
@ConfigurationProperties(prefix = "tenant.routing")
public class TenantRoutingProperties {
/** 是否启用租户路由 */
private boolean enabled = false;
private boolean enabled = true;
/** 租户 ID 请求头 */
private String tenantHeader = "X-Tenant-Id";
@ -21,6 +39,9 @@ public class TenantRoutingProperties {
/** 服务组分隔符 */
private String groupSeparator = "TENANT_";
/** 默认租户 ID当未指定时使用 */
private String defaultTenantId = "1";
/** 共享服务列表(不区分租户,所有租户共用) */
private List<String> sharedServices = Arrays.asList(
"fund-gateway",
@ -28,10 +49,10 @@ public class TenantRoutingProperties {
"fund-file"
);
/** 默认租户 ID当未指定时使用 */
private String defaultTenantId = "1";
/** 租户服务配置映射 */
private Map<String, TenantServiceConfig> services = new HashMap<>();
/** 租户服务配置(旧版兼容) */
private Map<String, TenantServiceConfig> tenantConfigs = new HashMap<>();
// Getters and Setters
@ -68,6 +89,14 @@ public class TenantRoutingProperties {
this.groupSeparator = groupSeparator;
}
public String getDefaultTenantId() {
return defaultTenantId;
}
public void setDefaultTenantId(String defaultTenantId) {
this.defaultTenantId = defaultTenantId;
}
public List<String> getSharedServices() {
return sharedServices;
}
@ -76,12 +105,12 @@ public class TenantRoutingProperties {
this.sharedServices = sharedServices;
}
public String getDefaultTenantId() {
return defaultTenantId;
public Map<String, TenantServiceConfig> getServices() {
return services;
}
public void setDefaultTenantId(String defaultTenantId) {
this.defaultTenantId = defaultTenantId;
public void setServices(Map<String, TenantServiceConfig> services) {
this.services = services;
}
public Map<String, TenantServiceConfig> getTenantConfigs() {
@ -109,21 +138,76 @@ public class TenantRoutingProperties {
return sharedServices.contains(serviceName);
}
/**
* 获取服务的 VIP 租户列表
*/
public List<String> 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<String> 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<String> vipTenants = new ArrayList<>();
/** 是否回退到共享实例 */
private boolean fallbackToShared = true;
/** 租户 ID */
private String tenantId;
/** 服务实例配置 */
private Map<String, ServiceInstanceConfig> services = new HashMap<>();
private Map<String, ServiceInstanceConfig> instances = new HashMap<>();
/** 数据库配置(一库一租户模式) */
private DatabaseConfig database;
// Getters and Setters
public List<String> getVipTenants() {
return vipTenants;
}
public void setVipTenants(List<String> 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;
}
@ -132,12 +216,12 @@ public class TenantRoutingProperties {
this.tenantId = tenantId;
}
public Map<String, ServiceInstanceConfig> getServices() {
return services;
public Map<String, ServiceInstanceConfig> getInstances() {
return instances;
}
public void setServices(Map<String, ServiceInstanceConfig> services) {
this.services = services;
public void setInstances(Map<String, ServiceInstanceConfig> instances) {
this.instances = instances;
}
public DatabaseConfig getDatabase() {

View File

@ -17,12 +17,22 @@ spring:
namespace: ${NACOS_NAMESPACE:}
group: DEFAULT_GROUP
enabled: true
metadata:
service-type: gateway
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
# 全局跨域配置
globalcors:
cors-configurations:
'[/**]':
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
routes:
- id: fund-sys
uri: lb://fund-sys
@ -30,6 +40,7 @@ spring:
- Path=/api/sys/**
filters:
- StripPrefix=1
# 租户感知负载均衡(自动添加 tenant-group 请求头)
- id: fund-cust
uri: lb://fund-cust
predicates:
@ -75,8 +86,46 @@ spring:
# JWT 配置
jwt:
secret: YourSecretKeyForJWTTokenGenerationMustBeAtLeast256BitsLong
expiration: 86400000
secret: ${JWT_SECRET:YourSecretKeyForJWTTokenGenerationMustBeAtLeast256BitsLong}
expiration: ${JWT_EXPIRATION:86400000}
# ==================== 多租户混合模式配置 ====================
tenant:
routing:
# 启用租户感知负载均衡
enabled: true
# 默认租户ID
default-tenant-id: 1
# 租户服务配置定义每个服务的VIP租户
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
fund-req:
vip-tenants: []
fallback-to-shared: true
fund-exp:
vip-tenants: []
fallback-to-shared: true
fund-receipt:
vip-tenants: []
fallback-to-shared: true
fund-report:
vip-tenants: []
fallback-to-shared: true
fund-file:
vip-tenants: []
fallback-to-shared: true
# Actuator 监控端点配置
management:
@ -98,6 +147,7 @@ management:
metrics:
tags:
application: ${spring.application.name}
service-type: gateway
distribution:
percentiles-histogram:
http.server.requests: true
@ -109,5 +159,8 @@ logging:
level:
root: INFO
com.fundplatform: DEBUG
# 多租户负载均衡日志
com.fundplatform.common.loadbalancer: DEBUG
com.fundplatform.gateway.filter: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n"
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%X{tenantId}] %-5level %logger{36} - %msg%n"

View File

@ -38,6 +38,12 @@ spring:
namespace: ${NACOS_NAMESPACE:}
group: DEFAULT_GROUP
enabled: true
# 多租户元数据配置(支持混合模式负载均衡)
metadata:
tenant-id: ${TENANT_ID:1}
tenant-group: ${TENANT_GROUP:}
# 服务实例权重VIP实例可配置更高权重
weight: ${NACOS_WEIGHT:1}
# MyBatis Plus 配置
mybatis-plus:
@ -49,6 +55,31 @@ mybatis-plus:
logic-delete-value: 1
logic-not-delete-value: 0
# ==================== 多租户混合模式配置 ====================
tenant:
routing:
# 启用租户感知负载均衡
enabled: true
# 默认租户ID
default-tenant-id: 1
# 租户服务配置
services:
fund-sys:
# VIP租户列表优先路由到专属实例
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
# Actuator 监控端点配置
management:
endpoints:
@ -69,6 +100,10 @@ management:
metrics:
tags:
application: ${spring.application.name}
# 多租户监控标签
tenant_id: ${TENANT_ID:1}
tenant_group: ${TENANT_GROUP:shared}
instance_type: ${TENANT_GROUP:shared}
distribution:
percentiles-histogram:
http.server.requests: true
@ -80,5 +115,8 @@ logging:
level:
root: INFO
com.fundplatform: DEBUG
# 多租户负载均衡日志
com.fundplatform.common.loadbalancer: DEBUG
com.fundplatform.common.nacos: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n"
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%X{tenantId}] %-5level %logger{36} - %msg%n"