# 多租户配置示例 ## 场景一:一库多租户(SaaS 模式) ### Gateway 配置 ```yaml # fund-gateway/src/main/resources/application.yml server: port: 8000 spring: application: name: fund-gateway cloud: nacos: discovery: server-addr: localhost:8848 username: nacos password: nacos gateway: routes: - id: fund-sys uri: lb://fund-sys predicates: - Path=/sys/** filters: - StripPrefix=1 - id: fund-cust uri: lb://fund-cust predicates: - Path=/cust/** filters: - StripPrefix=1 # 不需要启用租户路由,所有租户共享实例 tenant: routing: enabled: false ``` ### 业务服务配置(所有租户共用) ```yaml # fund-sys/src/main/resources/application.yml server: port: 8100 spring: application: name: fund-sys cloud: nacos: discovery: server-addr: localhost:8848 username: nacos password: nacos # 不需要特殊元数据配置 datasource: url: jdbc:mysql://localhost:3306/fund_sys?useUnicode=true&characterEncoding=utf8 username: root password: ${DB_PASSWORD} hikari: maximum-pool-size: 20 mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml configuration: map-underscore-to-camel-case: true # 不启用租户路由 tenant: routing: enabled: false ``` ### Service 层租户 ID 处理 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public void saveUser(User user) { // 设置默认租户 ID(如果未提供) if (user.getTenantId() == null) { Long tenantId = TenantContextHolder.getTenantId(); if (tenantId == null) { tenantId = 1L; // 默认租户 } user.setTenantId(tenantId); } userMapper.insert(user); } @Override public List listUsers() { // 自动添加租户过滤条件 Long tenantId = TenantContextHolder.getTenantId(); return userMapper.selectList(new LambdaQueryWrapper() .eq(User::getTenantId, tenantId)); } } ``` --- ## 场景二:一库一租户(私有化部署) ### Gateway 配置(支持租户路由) ```yaml # fund-gateway/src/main/resources/application.yml server: port: 8000 spring: application: name: fund-gateway cloud: nacos: discovery: server-addr: localhost:8848 username: nacos password: nacos gateway: routes: - id: fund-sys uri: lb://fund-sys predicates: - Path=/sys/** filters: - StripPrefix=1 # 报表服务是共享的 - id: fund-report uri: lb://fund-report predicates: - Path=/report/** filters: - StripPrefix=1 # 启用租户路由 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 # 租户专属配置 tenant-configs: tenant_001: tenant-id: tenant_001 services: fund-sys: service-name: fund-sys port: 8100 replicas: 2 fund-cust: service-name: fund-cust port: 8110 replicas: 1 database: url: jdbc:mysql://db-tenant001.com:3306/tenant_001_db username: t001 password: ${DB_PASSWORD_TENANT001} tenant_002: tenant-id: tenant_002 services: fund-sys: service-name: fund-sys port: 8101 replicas: 1 fund-cust: service-name: fund-cust port: 8111 replicas: 1 database: url: jdbc:mysql://db-tenant002.com:3306/tenant_002_db username: t002 password: ${DB_PASSWORD_TENANT002} ``` ### 租户专属服务实例配置 ```yaml # fund-sys 租户 001 实例配置 # fund-sys-tenant001-instance1.yml server: port: 8100 spring: application: name: fund-sys cloud: nacos: discovery: server-addr: localhost:8848 username: nacos password: nacos metadata: tenant-id: tenant_001 tenant-group: TENANT_TENANT_001 datasource: url: jdbc:mysql://db-tenant001.com:3306/tenant_001_db username: t001 password: ${DB_PASSWORD_TENANT001} driver-class-name: com.mysql.cj.jdbc.Driver tenant: routing: enabled: true ``` ```yaml # fund-sys 租户 002 实例配置 # fund-sys-tenant002-instance1.yml server: port: 8101 spring: application: name: fund-sys cloud: nacos: discovery: server-addr: localhost:8848 username: nacos password: nacos metadata: tenant-id: tenant_002 tenant-group: TENANT_TENANT_002 datasource: url: jdbc:mysql://db-tenant002.com:3306/tenant_002_db username: t002 password: ${DB_PASSWORD_TENANT002} driver-class-name: com.mysql.cj.jdbc.Driver tenant: routing: enabled: true ``` ### 启动脚本示例 ```bash #!/bin/bash # 启动租户 001 的系统服务(2 个实例) echo "Starting fund-sys for tenant_001 (instance 1)..." nohup java -jar fund-sys.jar \ --spring.cloud.nacos.discovery.metadata.tenant-id=tenant_001 \ --spring.cloud.nacos.discovery.metadata.tenant-group=TENANT_TENANT_001 \ --server.port=8100 \ --spring.datasource.url=jdbc:mysql://db-tenant001.com:3306/tenant_001_db \ > logs/fund-sys-tenant001-instance1.log 2>&1 & echo "Starting fund-sys for tenant_001 (instance 2)..." nohup java -jar fund-sys.jar \ --spring.cloud.nacos.discovery.metadata.tenant-id=tenant_001 \ --spring.cloud.nacos.discovery.metadata.tenant-group=TENANT_TENANT_001 \ --server.port=8101 \ --spring.datasource.url=jdbc:mysql://db-tenant001.com:3306/tenant_001_db \ > logs/fund-sys-tenant001-instance2.log 2>&1 & # 启动租户 002 的系统服务(1 个实例) echo "Starting fund-sys for tenant_002 (instance 1)..." nohup java -jar fund-sys.jar \ --spring.cloud.nacos.discovery.metadata.tenant-id=tenant_002 \ --spring.cloud.nacos.discovery.metadata.tenant-group=TENANT_TENANT_002 \ --server.port=8102 \ --spring.datasource.url=jdbc:mysql://db-tenant002.com:3306/tenant_002_db \ > logs/fund-sys-tenant002-instance1.log 2>&1 & # 启动客户服务(共享服务,所有租户共用) echo "Starting fund-cust (shared service)..." nohup java -jar fund-cust.jar \ --server.port=8110 \ --spring.datasource.url=jdbc:mysql://localhost:3306/fund_cust \ > logs/fund-cust-shared.log 2>&1 & echo "All services started!" ``` --- ## 场景三:混合模式(部分租户独立部署) ```yaml # Gateway 配置 tenant: routing: enabled: true default-tenant-id: "1" shared-services: - fund-gateway - fund-report - fund-file # 只有大客户有独立部署 tenant-configs: # VIP 客户:独立部署 vip_customer: tenant-id: vip_customer services: fund-sys: service-name: fund-sys port: 8200 replicas: 3 fund-cust: service-name: fund-cust port: 8210 replicas: 2 database: url: jdbc:mysql://vip-db.com:3306/vip_db username: vip password: xxx # 中小客户:共享部署(不在此配置,使用默认配置) ``` --- ## 环境变量配置(生产环境推荐) ```bash # .env 文件 # Nacos 配置 NACOS_SERVER_ADDR=nacos.prod.com:8848 NACOS_USERNAME=nacos NACOS_PASSWORD=${NACOS_PROD_PASSWORD} # 数据库配置 DB_HOST_PROD=mysql.prod.com DB_PORT_PROD=3306 DB_USERNAME_PROD=root DB_PASSWORD_PROD=${DB_PROD_PASSWORD} # 租户配置 TENANT_ROUTING_ENABLED=true TENANT_DEFAULT_ID=1 # 租户 001 配置 TENANT_001_ID=tenant_001 TENANT_001_DB_HOST=db-tenant001.com TENANT_001_DB_USERNAME=t001 TENANT_001_DB_PASSWORD=${TENANT001_PASSWORD} # 租户 002 配置 TENANT_002_ID=tenant_002 TENANT_002_DB_HOST=db-tenant002.com TENANT_002_DB_USERNAME=t002 TENANT_002_DB_PASSWORD=${TENANT002_PASSWORD} ``` ```yaml # application-prod.yml spring: cloud: nacos: discovery: server-addr: ${NACOS_SERVER_ADDR} username: ${NACOS_USERNAME} password: ${NACOS_PASSWORD} tenant: routing: enabled: ${TENANT_ROUTING_ENABLED:false} default-tenant-id: ${TENANT_DEFAULT_ID:1} tenant-configs: tenant_001: tenant-id: ${TENANT_001_ID} database: url: jdbc:mysql://${TENANT_001_DB_HOST}:${DB_PORT_PROD}/tenant_001_db username: ${TENANT_001_DB_USERNAME} password: ${TENANT_001_DB_PASSWORD} ``` --- **文档版本**: v1.0 **最后更新**: 2026-02-18