# 租户隔离策略
**本文档引用的文件**
- [Tenant.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/Tenant.cs)
- [TenantStore.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.MultiTenancy.Saas/LINGYUN/Abp/MultiTenancy/Saas/TenantStore.cs)
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs)
- [TenantConfigurationCache.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/MultiTenancy/TenantConfigurationCache.cs)
- [TenantSynchronizer.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs)
- [TenantConnectionString.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/TenantConnectionString.cs)
- [ITenantValidator.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/ITenantValidator.cs)
## 目录
1. [引言](#引言)
2. [租户数据存储策略](#租户数据存储策略)
3. [租户配置继承与覆盖机制](#租户配置继承与覆盖机制)
4. [访问控制与安全考虑](#访问控制与安全考虑)
5. [性能优化方法](#性能优化方法)
6. [跨租户数据共享实现](#跨租户数据共享实现)
7. [租户配置优先级规则](#租户配置优先级规则)
8. [实际代码示例](#实际代码示例)
9. [结论](#结论)
## 引言
本文档详细介绍了平台服务的多租户隔离策略,涵盖了租户级别的数据设计、存储策略、访问控制和性能优化方法。系统通过完善的租户配置继承与覆盖机制,确保了不同租户之间的数据隔离和安全性。文档还解释了租户配置的优先级规则和合并策略,并提供了跨租户数据共享的实现方式。
## 租户数据存储策略
平台采用基于租户ID的数据隔离策略,每个租户拥有独立的数据存储空间。系统通过`Tenant`实体类管理租户信息,包括租户名称、状态、启用时间、禁用时间等核心属性。租户连接字符串通过`TenantConnectionString`实体进行管理,实现了租户特定数据库连接的灵活配置。
```mermaid
classDiagram
class Tenant {
+Guid Id
+string Name
+string NormalizedName
+bool IsActive
+DateTime? EnableTime
+DateTime? DisableTime
+Collection ConnectionStrings
+SetEnableTime(DateTime?)
+SetDisableTime(DateTime?)
+FindDefaultConnectionString() string
+FindConnectionString(string) string
+SetDefaultConnectionString(string)
+SetConnectionString(string, string)
+RemoveConnectionString(string)
}
class TenantConnectionString {
+Guid TenantId
+string Name
+string Value
+SetValue(string)
+GetKeys() object[]
}
Tenant "1" -- "0..*" TenantConnectionString : 包含
```
**图源**
- [Tenant.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/Tenant.cs)
- [TenantConnectionString.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/TenantConnectionString.cs)
**章节来源**
- [Tenant.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/Tenant.cs#L41-L89)
- [TenantConnectionString.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/TenantConnectionString.cs#L0-L36)
## 租户配置继承与覆盖机制
系统实现了灵活的租户配置继承与覆盖机制。当租户需要特定配置时,可以在租户级别进行设置,这些设置会覆盖全局默认配置。`TenantStore`类负责管理租户配置的获取和缓存,通过分布式缓存提高配置读取性能。
```mermaid
sequenceDiagram
participant Client as 客户端
participant TenantStore as TenantStore
participant Cache as 分布式缓存
participant Service as TenantAppService
Client->>TenantStore : FindAsync(id/name)
TenantStore->>Cache : GetAsync(cacheKey)
alt 缓存命中
Cache-->>TenantStore : 返回缓存项
TenantStore-->>Client : 返回租户配置
else 缓存未命中
Cache-->>TenantStore : null
TenantStore->>Service : GetAsync(id/name)
Service->>TenantRepository : 查询租户数据
TenantRepository-->>Service : 返回租户实体
Service->>Service : 获取连接字符串
Service-->>TenantStore : 返回租户DTO
TenantStore->>Cache : SetAsync(cacheKey, cacheItem)
Cache-->>TenantStore : 缓存成功
TenantStore-->>Client : 返回租户配置
end
```
**图源**
- [TenantStore.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.MultiTenancy.Saas/LINGYUN/Abp/MultiTenancy/Saas/TenantStore.cs)
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs)
**章节来源**
- [TenantStore.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.MultiTenancy.Saas/LINGYUN/Abp/MultiTenancy/Saas/TenantStore.cs#L43-L148)
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs#L109-L147)
## 访问控制与安全考虑
系统实施严格的访问控制机制,确保租户数据的安全性。`ITenantValidator`接口定义了租户验证契约,允许在租户创建或更新时执行自定义验证逻辑。所有敏感操作都受到权限控制,只有授权用户才能执行租户配置的修改。
```mermaid
flowchart TD
Start([开始]) --> CheckAuth["检查用户权限"]
CheckAuth --> AuthValid{"权限有效?"}
AuthValid --> |否| ReturnError["返回权限错误"]
AuthValid --> |是| ValidateInput["验证输入参数"]
ValidateInput --> InputValid{"输入有效?"}
InputValid --> |否| ReturnValidationError["返回验证错误"]
InputValid --> |是| CheckTenant["检查租户状态"]
CheckTenant --> IsActive{"租户激活?"}
IsActive --> |否| ReturnInactive["返回租户未激活"]
IsActive --> |是| CheckTime["检查时间范围"]
CheckTime --> TimeValid{"在有效期内?"}
TimeValid --> |否| ReturnExpired["返回已过期"]
TimeValid --> |是| ExecuteOperation["执行操作"]
ExecuteOperation --> UpdateCache["更新配置缓存"]
UpdateCache --> PublishEvent["发布事件"]
PublishEvent --> End([结束])
ReturnError --> End
ReturnValidationError --> End
ReturnInactive --> End
ReturnExpired --> End
```
**图源**
- [ITenantValidator.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/ITenantValidator.cs)
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs)
**章节来源**
- [ITenantValidator.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/ITenantValidator.cs#L0-L7)
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs#L146-L184)
## 性能优化方法
为提高系统性能,平台采用了多层次的缓存策略。`TenantConfigurationCache`类使用分布式缓存存储租户配置,减少数据库查询压力。当租户配置发生变化时,通过事件总线通知所有相关服务刷新本地缓存,确保配置的一致性。
```mermaid
graph TB
subgraph "缓存层"
DC[(分布式缓存)]
LC[(本地缓存)]
end
subgraph "服务层"
TSC[TenantStore]
TCC[TenantConfigurationCache]
end
subgraph "数据层"
DB[(数据库)]
end
Client --> TSC
TSC --> DC
DC --> |缓存命中| TSC
DC --> |缓存未命中| TCC
TCC --> DB
DB --> TCC
TCC --> DC
DC --> TSC
TSC --> Client
Event[配置变更事件] --> TCC
TCC --> |刷新缓存| DC
```
**图源**
- [TenantConfigurationCache.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/MultiTenancy/TenantConfigurationCache.cs)
- [TenantStore.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.MultiTenancy.Saas/LINGYUN/Abp/MultiTenancy/Saas/TenantStore.cs)
**章节来源**
- [TenantConfigurationCache.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/MultiTenancy/TenantConfigurationCache.cs#L0-L59)
- [TenantStore.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.MultiTenancy.Saas/LINGYUN/Abp/MultiTenancy/Saas/TenantStore.cs#L79-L109)
## 跨租户数据共享实现
虽然系统主要强调数据隔离,但也支持有限的跨租户数据共享场景。通过事件总线机制,租户间的变更可以被其他服务订阅和处理。`TenantSynchronizer`类监听租户相关的分布式事件,并在配置变更时触发相应的同步操作。
```mermaid
sequenceDiagram
participant Publisher as 事件发布者
participant EventBus as 分布式事件总线
participant Subscriber as TenantSynchronizer
participant Cache as 配置缓存
Publisher->>EventBus : 发布租户变更事件
EventBus->>Subscriber : 传递事件
Subscriber->>Subscriber : HandleEventAsync()
Subscriber->>Cache : RefreshAsync()
Cache->>Cache : 清除旧缓存
Cache-->>Subscriber : 刷新完成
Subscriber-->>EventBus : 确认处理
```
**图源**
- [TenantSynchronizer.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs)
- [TenantConfigurationCache.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/MultiTenancy/TenantConfigurationCache.cs)
**章节来源**
- [TenantSynchronizer.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/EventBus/Distributed/TenantSynchronizer.cs#L32-L52)
- [TenantConfigurationCache.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/MultiTenancy/TenantConfigurationCache.cs#L0-L10)
## 租户配置优先级规则
系统遵循明确的配置优先级规则:租户级别配置 > 全局默认配置。当查询租户配置时,系统首先尝试从缓存中获取,如果缓存中不存在,则从数据库加载并建立新的缓存项。这种机制确保了配置读取的高效性和一致性。
```mermaid
flowchart LR
A[请求租户配置] --> B{缓存中存在?}
B --> |是| C[返回缓存配置]
B --> |否| D[从数据库加载]
D --> E[创建新缓存项]
E --> F[返回配置]
G[配置变更] --> H[清除相关缓存]
H --> I[下一次请求重新加载]
```
**章节来源**
- [TenantStore.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.MultiTenancy.Saas/LINGYUN/Abp/MultiTenancy/Saas/TenantStore.cs#L43-L82)
- [TenantConfigurationCache.cs](file://aspnet-core/services/LY.MicroService.Applications.Single/MultiTenancy/TenantConfigurationCache.cs#L0-L59)
## 实际代码示例
以下示例展示了租户数据的查询和更新操作:
```mermaid
sequenceDiagram
participant Client as 客户端
participant AppService as TenantAppService
participant Repository as TenantRepository
participant Cache as 配置缓存
participant EventBus as 事件总线
Client->>AppService : GetAsync(tenantId)
AppService->>Repository : GetAsync(tenantId)
Repository-->>AppService : 返回租户实体
AppService-->>Client : 返回租户DTO
Client->>AppService : SetConnectionStringAsync(tenantId, input)
AppService->>Repository : GetAsync(tenantId)
Repository-->>AppService : 返回租户实体
AppService->>AppService : 记录旧连接字符串
AppService->>AppService : 设置新连接字符串
AppService->>Repository : UpdateAsync(tenant)
Repository-->>AppService : 更新成功
AppService->>EventBus : 发布连接字符串更新事件
EventBus-->>AppService : 事件发布成功
AppService-->>Client : 返回更新结果
```
**图源**
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs)
- [TenantRepository.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Domain/LINGYUN/Abp/Saas/Tenants/TenantRepository.cs)
**章节来源**
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs#L214-L255)
- [TenantAppService.cs](file://aspnet-core/modules/saas/LINGYUN.Abp.Saas.Application/LINGYUN/Abp/Saas/Tenants/TenantAppService.cs#L251-L291)
## 结论
本平台的多租户隔离策略通过完善的架构设计和实现,确保了租户数据的安全性、隔离性和高性能访问。系统采用分层缓存机制优化性能,通过事件驱动架构保证配置的一致性,并实施严格的访问控制保障数据安全。租户配置的继承与覆盖机制提供了灵活性,同时保持了系统的可维护性。