# 租户隔离策略 **本文档引用的文件** - [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) ## 结论 本平台的多租户隔离策略通过完善的架构设计和实现,确保了租户数据的安全性、隔离性和高性能访问。系统采用分层缓存机制优化性能,通过事件驱动架构保证配置的一致性,并实施严格的访问控制保障数据安全。租户配置的继承与覆盖机制提供了灵活性,同时保持了系统的可维护性。