电竞比分网-中国电竞赛事及体育赛事平台

分享

ABP理論學(xué)習(xí)之多租戶

 昵稱10504424 2015-12-14

返回總目錄


本篇目錄

什么是多租戶

維基百科:“軟件多租戶是指一種軟件架構(gòu),在這種軟件架構(gòu)中,軟件的一個(gè)實(shí)例運(yùn)行在服務(wù)器上并且為多個(gè)租戶服務(wù)”。一個(gè)租戶是一組共享該軟件實(shí)例特定權(quán)限的用戶。有了多租戶架構(gòu),軟件應(yīng)用被設(shè)計(jì)成為每個(gè)租戶提供一個(gè) 專用的實(shí)例包括該實(shí)例的數(shù)據(jù)的共享,還可以共享配置,用戶管理,租戶自己的功能和非功能屬性。多租戶和多實(shí)例架構(gòu)相比,多租戶分離了代表不同的租戶操作的多個(gè)實(shí)例。

多租戶用于創(chuàng)建Saas(Software as-a service)應(yīng)用(云處理)。有幾種類型的多租戶:

多部署-多數(shù)據(jù)庫(kù)

這實(shí)際上不是多租戶。但是,如果我們?yōu)?strong>每個(gè)具有分開數(shù)據(jù)庫(kù)的客戶(租戶)運(yùn)行該應(yīng)用的一個(gè)實(shí)例,那么我們可以在單個(gè)服務(wù)器上為多個(gè)租戶提供服務(wù)。我們可以確定該應(yīng)用的多個(gè)實(shí)例在相同的服務(wù)器環(huán)境不會(huì)相互沖突。

這個(gè)對(duì)于一個(gè)不是為多租戶設(shè)計(jì)的已存在應(yīng)用也是可能的。創(chuàng)建這么一個(gè)應(yīng)用更容易,因?yàn)樵搼?yīng)用不需要了解多租戶。但這種方式存在安裝,使用和維護(hù)問(wèn)題。

單部署-多數(shù)據(jù)庫(kù)

在這種情況下,我們可以在一個(gè)服務(wù)器上運(yùn)行應(yīng)用的單個(gè)實(shí)例。對(duì)于每個(gè)登錄用戶,我們從master database中檢測(cè)該用戶的租戶,并獲得該租戶的數(shù)據(jù)庫(kù)信息(連接字符串)。然后我們可以將連接字符串存儲(chǔ)到像session一樣的變量中,同時(shí),使用這個(gè)租戶特定的連接字符串執(zhí)行所有的數(shù)據(jù)庫(kù)操作。

某種程度上,這樣的應(yīng)用應(yīng)該設(shè)計(jì)成多租戶。但是大多數(shù)的應(yīng)用都獨(dú)立于多租戶。這種方式也存在一些安裝,使用和維護(hù)問(wèn)題。我們應(yīng)該為每個(gè)租戶創(chuàng)建并維護(hù)一個(gè)分離的數(shù)據(jù)庫(kù)。

單部署-單數(shù)據(jù)庫(kù)

這是最真實(shí)的多租戶架構(gòu):我們只將具有單個(gè)數(shù)據(jù)庫(kù)應(yīng)用的單個(gè)實(shí)例部署到單個(gè)服務(wù)器上。在(RDBMS)每個(gè)表中,都存在一個(gè)TenantId(或相似)字段,該字段用于分離每個(gè)租戶之間的數(shù)據(jù)。

這種方法安裝和維護(hù)都很簡(jiǎn)單,但唯獨(dú)創(chuàng)建這么一個(gè)應(yīng)用很難,因?yàn)槲覀儽仨氁柚挂粋€(gè)租戶讀取或?qū)懭肫渌鈶舻臄?shù)據(jù)。我們可以為每個(gè)數(shù)據(jù)庫(kù)的讀?。╯elect)操作添加一個(gè)TenantId過(guò)濾器。而且,我們可以在每次寫入的時(shí)候檢查一下該實(shí)體是否和當(dāng)前的租戶相關(guān)。這是乏味而易于出錯(cuò)的,但ABP通過(guò)使用自動(dòng)的數(shù)據(jù)過(guò)濾幫助我們處理這個(gè)事情。

如果我們有很多具有大量數(shù)據(jù)的租戶,那么這種方法可能會(huì)有性能問(wèn)題。我們可以使用關(guān)系型數(shù)據(jù)庫(kù)的表分割特征或者將租戶按組分到不同的服務(wù)器上。

ABP中的多租戶

ABP提供了創(chuàng)建單部署,單數(shù)據(jù)庫(kù),多租戶架構(gòu)的基礎(chǔ)設(shè)施。

開啟多租戶

多租戶默認(rèn)是關(guān)閉的。我們可以在模塊的PreInitialize方法中開啟,如下所示:

Configuration.MultiTenancy.IsEnabled = true; 

租主vs租戶

首先,我們應(yīng)該定義多租戶系統(tǒng)中的兩個(gè)條目:

  • 租主(Host):租主是單例的(只有一個(gè)租主)。租主會(huì)對(duì)創(chuàng)建和管理租戶負(fù)責(zé)。因此,一個(gè)“租主用戶”比所有的租戶等級(jí)更高,并獨(dú)立于所有租戶,同時(shí)還能控制他們。
  • 租戶(Tenant):租主的一個(gè)客戶,具有自己的用戶角色,權(quán)限,設(shè)置等。每個(gè)租戶都可以完全獨(dú)立于其他租戶使用應(yīng)用。一個(gè)多租戶應(yīng)用會(huì)有一個(gè)或多個(gè)租戶。如果是一個(gè)CRM應(yīng)用,那么不同的租戶也有它們自己的賬戶,契約,產(chǎn)品和訂單。因此,當(dāng)我們說(shuō)“**租戶用戶”的時(shí)候,意思就是一個(gè)租戶擁有的用戶。

Session

ABP定義了一個(gè)獲取當(dāng)前用戶租戶id的IAbpSession接口。該接口用于多租戶獲取當(dāng)前的租戶id。因此,它可以基于當(dāng)前的租戶id過(guò)濾數(shù)據(jù)。ABP中有以下規(guī)則:

  • 如果UserId和TenantId都是null,那么當(dāng)前的用戶沒有登錄到系統(tǒng)。因此,我們可以不知道當(dāng)前用戶是否是一個(gè)租主用戶還是一個(gè)租戶用戶。在這種情況下,用戶不能訪問(wèn)授權(quán)的內(nèi)容。
  • 如果UserId不是null,TenantId是null,那么當(dāng)前用戶是一個(gè)租主用戶。
  • 如果UserId不是null,TenantId也不是null,那么當(dāng)前用戶是租戶用戶。

更多關(guān)于session的信息請(qǐng)看后面的Session一節(jié)。

數(shù)據(jù)過(guò)濾器

當(dāng)從數(shù)據(jù)庫(kù)中檢索實(shí)體時(shí),我們必須添加一個(gè)TenantId過(guò)濾器來(lái)只獲得當(dāng)前的租戶實(shí)體。當(dāng)你為實(shí)體實(shí)現(xiàn)了IMustHaveTenant和IMayHaveTenant兩個(gè)接口之一時(shí),ABP會(huì)自動(dòng)地完成數(shù)據(jù)過(guò)濾。

IMustHaveTenant接口

該接口通過(guò)定義TenantId屬性來(lái)區(qū)分不同租戶的實(shí)體。一個(gè)實(shí)現(xiàn)了IMustHaveTenant的實(shí)體例子如下:

public class Product : Entity, IMustHaveTenant
{
    public int TenantId { get; set; }
        
    public string Name { get; set; }
    
    //...其他屬性
}

這樣,ABP知道這是一個(gè)特定租戶的實(shí)體,并且會(huì)自動(dòng)地將一個(gè)租戶的實(shí)體從其他實(shí)體中分離出來(lái)。

IMayHaveTenant接口

我們可能需要在租戶和租戶之間共享一個(gè)實(shí)體類型。因此,一個(gè)實(shí)體可能會(huì)被一個(gè)租戶或租主擁有。IMayHaveTenant接口也定義了TenantId(類似于IMustHaveTenant),但在這種情況下是nullable。實(shí)現(xiàn)了IMayHaveTenant的一個(gè)實(shí)體例子:

public class Role : Entity, IMayHaveTenant
{
    public int? TenantId { get; set; }
        
    public string RoleName { get; set; }
    
    //...其他屬性
}

我們可能會(huì)使用相同的Role類來(lái)存儲(chǔ)租主角色和租戶角色。這種情況下,TenantId表明這是一個(gè)租戶實(shí)體還是一個(gè)租主實(shí)體。null值表示這是一個(gè)租主實(shí)體,非null值表示這被一個(gè)租戶擁有,該租戶的Id是TenantId

IMayHaveTenant不像IMustHaveTenant一樣常用。比如,一個(gè)Product類可以不實(shí)現(xiàn)IMayHaveTenant接口,因?yàn)镻roduct和實(shí)際的應(yīng)用功能相關(guān),和管理租戶不相干。因此,要小心使用IMayHaveTenant接口,因?yàn)樗y維護(hù)租戶和租主共享的代碼。

保存實(shí)體

一個(gè)租戶用戶不應(yīng)該創(chuàng)建或編輯其他租戶的實(shí)體。如果相關(guān)的數(shù)據(jù)過(guò)濾器開啟了,那么ABP會(huì)檢查該實(shí)體相對(duì)于數(shù)據(jù)庫(kù)的改變。

想要獲得更多關(guān)于數(shù)據(jù)過(guò)濾器的信息,請(qǐng)看后面關(guān)于數(shù)據(jù)過(guò)濾器的博客。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多