本節目錄 什麼是多租戶 多部署-多資料庫 單部署-多資料庫 單部署-單資料庫 在ABP中的多租戶 啟用多租戶 Host vs Tenant Session Data Filters IMustHaveTenant IMayHaveTenant 保存實體 什麼是多租戶 維基百科:軟體多租戶是1個軟體架
本節目錄
- 什麼是多租戶
- 多部署-多資料庫
- 單部署-多資料庫
- 單部署-單資料庫
- 在ABP中的多租戶
- 啟用多租戶
- Host vs Tenant
- Session
- Data Filters
- IMustHaveTenant
- IMayHaveTenant
- 保存實體
什麼是多租戶
維基百科:軟體多租戶是1個軟體架構,軟體的1個實例跑在伺服器上,並且為多個租戶服務著.
1個租戶是指軟體中的公用1種特定許可權的一群用戶.
在多租戶的架構下,軟體可以為每個租戶提供獨立的數據,配置,用戶管理.
與多實例架構相比,為通過分離軟體實例提供給不同租戶的操作.
多租戶用於創建SaaS(Software as-a Service)應用(雲計算).
有以下幾種多租戶:
多部署-多資料庫
事實上,這不是多租戶.如果我們在單台伺服器上提供多租戶服務,通過分離資料庫,為每個租戶提供1個軟體實例.我們只需確保多個軟體實例在同1個伺服器中互不衝突.
已存在的應用幾乎都能實現.很容易創建這樣的應用,應用不需要關心多租戶.
但是他們部署,使用和維護都是問題.
單部署-多資料庫
在這種情況下,我們可以在伺服器上運行1個軟體的實例.每個用戶登錄的時候,我們從master資料庫中檢查用戶的租戶,然後獲取對應的租戶所在資料庫信息(連接字元串).
然後我們存儲連接字元串到session中,執行資料庫操作的時候使用這個特定的連接字元串.
在這個情況下,軟體需要設計成多租戶的.對於多租戶來說,軟體大部分是獨立的.
同樣這種軟體也存在安裝,使用和部署的問題.我們需要為每個租戶創建和部署資料庫.
單部署-單資料庫
這是最真實的多租戶架構:我們部署軟體的單個實例,部署單個資料庫到一臺伺服器上.
我們會在需要做多租戶的表中設計1個TenantId 欄位.
這是容易部署和維護的.但是創建這樣的軟體比較難.
因為,我們需要阻止1個租戶去讀寫其他租戶的數據.我們為每次數據讀操作可能需要添加1個TenantId filter.
同樣的,如果這個實體和當前租戶關聯.我們在每次寫的時候需要檢查.這是非常無趣且容易出錯的.
但是ABP會使用自動數據過濾幫助我們處理這些.
如果我們有多租戶的大量數據,這種方法可能會有性能問題.我們可以分表或者為1組租戶提供不同伺服器.
在ABP中的多租戶
ABP 提供了1個創建單部署,單資料庫,多租戶的架構框架支持.
啟用多租戶
多租戶預設是禁用的.我們可以在PreInitialize 中啟用.如下:
Configuration.MultiTenancy.IsEnabled = true;
Host vs Tenant
首先,我們說明多租戶的2個條目.
- 租戶:1個客戶有他自己的用戶,角色,許可權,設置...以及完全獨立其他租戶使用這個軟體.如果是1個CRM軟體,不同的租戶有他們自己的賬戶,聯繫人,產品和訂單.所以,當我們說'多租戶用戶',我們指的是屬於1個租戶的用戶.
- 租主:租主是唯一的.租主可以創建和管理租戶.所以,一個'租主用戶'是1個更高級別的,獨立所有租戶和管理他們.
Session
ABP定義了1個獲取當前用戶和租戶的介面IAbpSession .這個介面在多租戶下可以獲取當前租戶id.他會通過id過來數據.
- 如果UserId and TenantId都為null,當前用戶未登錄.所以,我們不知道當前用戶角色.這種情況下,不會授權操作.
- 如果UserId is not null and TenantId is null,我們認為當前用戶為host user.
- 如果UserId is not null and also TenantId is not null,我們認為當前用戶tenant user.
(See session documentation for more information on the session.)
Data Filters
當從數據中查詢實體,我們必須添加TenantId 獲取當前tenant的數據.當你的實體,實現2個介面其中之一的時候,ABP會自動實現.(IMustHaveTenant and IMayHaveTenant)
IMustHaveTenant
這個介面通過TenantId 屬性定義不同租戶.
public class Product : Entity, IMustHaveTenant { public int TenantId { get; set; } public string Name { get; set; } //...other properties }
這樣,ABP就知道這是1個租戶實體,會自動過濾tenant.
IMayHaveTenant
當我們需要在host和tenants共用實體時.即這個實體可能屬於tenant或者是host.IMayHaveTenant 介面可以定義1個可空的TenantId.
public class Role : Entity, IMayHaveTenant { public int? TenantId { get; set; } public string RoleName { get; set; } //...other properties }
以上例子中,我們用同1個Role類存儲Host roles and Tenant roles.當TenantId 屬性為null時,表示為host entity,不為null,表示這個實體屬於指定的tenant.
IMayHaveTenant 不像IMustHaveTenant常用.比如:Product 類不能實現IMayHaveTenant 介面,當Product 類和實際軟體需要相關,和tenants不不相關.
使用IMayHaveTenant 介面在host和tenant中共用,會更難維護代碼.
保存實體
1個租戶用戶無法創建和修改其他租戶實體.
只要data filters開啟,ABP會在保存數據前檢查確認.(See data filters document for more information on data filters.)