偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

我對(duì)實(shí)現(xiàn)多租戶系統(tǒng)的一點(diǎn)思考

開(kāi)發(fā) 項(xiàng)目管理
目前大部分的企業(yè)信息化都是私有化部署,局限于企業(yè)的內(nèi)部網(wǎng)絡(luò),無(wú)法實(shí)現(xiàn)遠(yuǎn)程協(xié)同辦公,所以越來(lái)越多的 To B 企業(yè)逐步轉(zhuǎn)向 SaaS(Software-as-a-Service,軟件即服務(wù)),SaaS 最早是美國(guó)Salesforce公司(1999年創(chuàng)立)創(chuàng)造的新軟件服務(wù)模式。

[[399862]]

本文轉(zhuǎn)載自微信公眾號(hào)「不止dotNET」,作者不止dotNET。轉(zhuǎn)載本文請(qǐng)聯(lián)系不止dotNET公眾號(hào)。

2020年突發(fā)的新冠疫情,讓在線協(xié)同辦公在疫情期間成為了剛需。我們也從 2020 年的 2月3 日開(kāi)始在家遠(yuǎn)程辦公,直到四月份。協(xié)同辦公軟件一下子火爆了起來(lái),釘釘、企業(yè)微信、特別是騰訊會(huì)議等都在疫情期間表現(xiàn)突出,呈現(xiàn)出井噴式的發(fā)展。

目前大部分的企業(yè)信息化都是私有化部署,局限于企業(yè)的內(nèi)部網(wǎng)絡(luò),無(wú)法實(shí)現(xiàn)遠(yuǎn)程協(xié)同辦公,所以越來(lái)越多的 To B 企業(yè)逐步轉(zhuǎn)向 SaaS(Software-as-a-Service,軟件即服務(wù)),SaaS 最早是美國(guó)Salesforce公司(1999年創(chuàng)立)創(chuàng)造的新軟件服務(wù)模式。這家公司的市值在 2019 年已經(jīng)超過(guò)1000億美元,國(guó)內(nèi)現(xiàn)在還處在發(fā)展中階段,前景還是十分廣闊的。

要將傳統(tǒng)的私有化部署的軟件重構(gòu)成支持 SaaS 模式,多租戶是一個(gè)邁不過(guò)去的坎,首先需要將系統(tǒng)改造成多租戶模式,然后再逐步實(shí)現(xiàn)計(jì)費(fèi)、系統(tǒng)監(jiān)控、用戶行為分析等功能。

我覺(jué)得多租戶的設(shè)計(jì)應(yīng)該分為三個(gè)層面來(lái)進(jìn)行討論,應(yīng)用、數(shù)據(jù)庫(kù)和中間件。

應(yīng)用

現(xiàn)在的項(xiàng)目或產(chǎn)品開(kāi)發(fā)幾乎都是前后端分離的開(kāi)發(fā)模式,應(yīng)用層主要指的是 WebAPI ,WebAPI 的改造有兩種方式:

1、每個(gè)租戶部署一套 WebAPI、上層通過(guò)域名或 Url 地址的解析進(jìn)行路由,當(dāng)有新租戶注冊(cè)的時(shí)候就動(dòng)態(tài)進(jìn)行對(duì)應(yīng)的 WebAPI 的部署,這種方式改造成本低,但運(yùn)維成本高,不建議使用,如果時(shí)間緊,可以當(dāng)過(guò)度階段的臨時(shí)方案。

2、所有的租戶共用一套 WebAPI ,在 WebAPI 中需要獲取到租戶信息(域名、Url參數(shù)、請(qǐng)求頭信息、Cookie 等),然后進(jìn)行租戶信息配置的切換。有新租戶創(chuàng)建的時(shí)候無(wú)需進(jìn)行新的 WebAPI 的創(chuàng)建,只需要初始化租戶基本信息即可。

在這種方式下,如果 Cluster1 的負(fù)載超過(guò)限度了,也要能夠進(jìn)行動(dòng)態(tài)切換,將其中的某些租戶切換到其他的 Cluester 中,如上圖。

在 WebAPI 的代碼實(shí)現(xiàn)上,可以參考 Abp 框架中多租戶的實(shí)現(xiàn),這里給出一個(gè)簡(jiǎn)化版本:

TenantConfiguration:租戶配置信息

  1. [Serializable
  2. public class TenantConfiguration 
  3.     public Guid Id { get; set; } 
  4.  
  5.     public string Code { get; set; } 
  6.  
  7.     public string Name { get; set; } 
  8.  
  9.     public TenantStatus TenantStatus { get; set; } 
  10.  
  11.     public string DBConfig { get; set; } 
  12.  
  13.     public string CacheConfig { get; set; } 
  14.  
  15.     public string MQConfig { get; set; } 
  16.  
  17.     public string MongoConfig { get; set; } 
  18.  
  19.     public TenantConfiguration() 
  20.     { 
  21.         TenantStatus = TenantStatus.Enable; 
  22.     } 
  23.  
  24.     public TenantConfiguration(Guid id, string name
  25.         : this() 
  26.     { 
  27.         
  28.         Id = id; 
  29.         Name = name
  30.     } 

TenantStore:從緩存或數(shù)據(jù)庫(kù)中獲取租戶配置信息

  1. public interface ITenantStore 
  2.     TenantConfiguration Find(string code); 
  3. public class TenantStore : ITenantStore 
  4.     public TenantConfiguration Find(string code) 
  5.     { 
  6.         //從緩存或數(shù)據(jù)庫(kù)進(jìn)行租戶配置信息獲取 
  7.         throw new NotImplementedException(); 
  8.     } 

CurrentTenant:當(dāng)前租戶類,用來(lái)存儲(chǔ)當(dāng)前租戶信息,以及切換租戶

  1. public interface ICurrentTenant 
  2.  
  3.     TenantConfiguration Config { get;} 
  4.     IDisposable Change(string code); 
  5. /// <summary> 
  6. /// 當(dāng)前租戶 
  7. /// </summary> 
  8. public class CurrentTenant:ICurrentTenant 
  9.     public ITenantStore _tenantStore; 
  10.     public CurrentTenant(ITenantStore tenantStore) 
  11.     { 
  12.         _tenantStore = tenantStore; 
  13.     } 
  14.  
  15.     public TenantConfiguration _config; 
  16.     public TenantConfiguration Config => _config; 
  17.  
  18.     /// <summary> 
  19.     /// 切換租戶 
  20.     /// </summary> 
  21.     /// <param name="code"></param> 
  22.     /// <returns></returns
  23.     public IDisposable Change(string code) 
  24.     { 
  25.         TenantConfiguration tenantConfig= _tenantStore.Find(code); 
  26.         if (tenantConfig == null
  27.         { 
  28.             throw new Exception("Tenant not found"); 
  29.         } 
  30.  
  31.         if (tenantConfig.TenantStatus != TenantStatus.Enable) 
  32.         { 
  33.             throw new Exception("Tenant is disabled or deleted"); 
  34.         } 
  35.  
  36.         return new DisposeAction(() => 
  37.         { 
  38.             _config = tenantConfig; 
  39.         }); 
  40.     } 

UrlTenantResolve:根據(jù) Url 參數(shù)進(jìn)行租戶解析

  1. public interface ITenantResolve 
  2.     string Resolve(HttpContext httpContext); 
  3. /// <summary> 
  4. ///  
  5. /// </summary> 
  6. public class UrlTenantResolve:ITenantResolve 
  7.  
  8.     public string Resolve(HttpContext httpContext) 
  9.     { 
  10.         return httpContext.Request.QueryString.HasValue 
  11.            ? httpContext.Request.Query["__tenant"].ToString() 
  12.            : null
  13.     } 

MultiTenancyMiddleware:租戶中間件,關(guān)于在 dotNET Core 中自定義中間件可以參考《dotNET Core 3.X 請(qǐng)求處理管道和中間件的理解》

  1. public class MultiTenancyMiddleware: IMiddleware 
  2.     protected readonly ITenantResolve _tenantResolve; 
  3.     private readonly ICurrentTenant _currentTenant; 
  4.  
  5.     public MultiTenancyMiddleware( 
  6.        ITenantResolve tenantResolve, 
  7.        ICurrentTenant currentTenant) 
  8.     { 
  9.         _tenantResolve = tenantResolve; 
  10.         _currentTenant = currentTenant; 
  11.     } 
  12.  
  13.     public async Task InvokeAsync(HttpContext context, RequestDelegate next
  14.     { 
  15.         var tenantCode = _tenantResolve.Resolve(context); 
  16.  
  17.         if (tenantCode != _currentTenant.Config.Code) 
  18.         { 
  19.             using (_currentTenant.Change(tenantCode)) 
  20.             { 
  21.                 await next(context); 
  22.             } 
  23.         } 
  24.         else 
  25.         { 
  26.             await next(context); 
  27.         } 
  28.  
  29.         await next(context); 
  30.     } 

數(shù)據(jù)庫(kù)

數(shù)據(jù)庫(kù)在這里指的是關(guān)系型數(shù)據(jù)庫(kù),用來(lái)存儲(chǔ)業(yè)務(wù)數(shù)據(jù),實(shí)現(xiàn)多租戶,就要對(duì)數(shù)據(jù)進(jìn)行隔離,通常的數(shù)據(jù)隔離方式有三種模式:

1、完全隔離,每個(gè)租戶使用獨(dú)立數(shù)據(jù)庫(kù);

2、部分共享,租戶共享一個(gè)數(shù)據(jù)庫(kù),以 schema 或者 table 區(qū)分;

3、完全共享,租戶共享相同的數(shù)據(jù)庫(kù)表,以 tenant_id 進(jìn)行區(qū)分

推薦使用第一種或第二種,隔離程度比較高,也比較容易做橫向擴(kuò)展,如果是第三種,需要處理數(shù)據(jù)的隔離問(wèn)題,需要處理單表大數(shù)據(jù)的問(wèn)題等,對(duì)技術(shù)要求比較高。

中間件

除了數(shù)據(jù)庫(kù),一個(gè)系統(tǒng)還需要依賴其他的一些中間件,比如緩存、消息隊(duì)列、文件存儲(chǔ):

  • 緩存:Redi
  • 消息隊(duì)列:RabbitMQ
  • 文件存儲(chǔ):MongoDB 的 GridFS

Redis

1、Redis 中使用數(shù)據(jù)庫(kù)的方式進(jìn)行租戶隔離;

2、Redis 可以通過(guò)修改配置文件的方式進(jìn)行數(shù)據(jù)庫(kù)的擴(kuò)展,默認(rèn)為 16 個(gè);3、通過(guò) Redis 分片集群的方式進(jìn)行部署,可以進(jìn)行橫向擴(kuò)展;3、在 Redis 集群中,官方推薦節(jié)點(diǎn)數(shù)量不超過(guò) 1000 個(gè),這個(gè)對(duì)于多租戶系統(tǒng)的前期來(lái)說(shuō)應(yīng)該是夠用了,如果到了租戶數(shù)量的爆發(fā)期,再進(jìn)行架構(gòu)的擴(kuò)展,比如,不同的租戶路由到不同的 Redis 集群中。

RabbitMQ

在 Rabbitmq 有 vhost 機(jī)制,可以一個(gè)租戶創(chuàng)建一個(gè)vhost,通過(guò) vhost 來(lái)進(jìn)行租戶的隔離,目前還沒(méi)查詢到 vhost 是否有上限,需要做進(jìn)一步驗(yàn)證。

MongoDB

MongoDB 中主要使用 GridFS 來(lái)進(jìn)行非結(jié)構(gòu)化數(shù)據(jù)的存儲(chǔ),通過(guò)創(chuàng)建數(shù)據(jù)庫(kù)的方式來(lái)進(jìn)行租戶的隔離,而且 MongoDB 支持分片的集群部署方式,可以進(jìn)行擴(kuò)展橫擴(kuò)展,在前期,一個(gè) MongoDB 集群應(yīng)該就夠用了。

最后

技術(shù)方案和架構(gòu)沒(méi)有最好的,只有最適合的,符合當(dāng)下的業(yè)務(wù)場(chǎng)景、團(tuán)隊(duì)的技術(shù)能力就可以,然后要做的就是做 MVP (最小可行性產(chǎn)品),進(jìn)而進(jìn)行系統(tǒng)的改造。

希望本文對(duì)您有所幫助!

 

責(zé)任編輯:武曉燕 來(lái)源: 不止dotNET
相關(guān)推薦

2014-09-17 10:30:25

代碼

2011-07-04 09:33:04

惠普轉(zhuǎn)型李艾科

2011-12-23 09:16:19

2014-09-23 11:21:05

代碼命名程序員架構(gòu)設(shè)計(jì)

2022-07-13 08:45:29

云原生容器網(wǎng)絡(luò)

2013-05-13 11:25:44

系統(tǒng)架構(gòu)

2013-05-14 12:06:26

.Net系統(tǒng)架構(gòu)架構(gòu)設(shè)計(jì)

2019-03-22 14:38:03

容器安全隔離

2013-03-06 10:19:56

重構(gòu)架構(gòu)設(shè)計(jì)

2011-07-18 16:33:20

sqlite

2022-04-06 07:14:29

區(qū)塊鏈網(wǎng)絡(luò)生態(tài)系統(tǒng)

2013-06-26 10:13:32

C語(yǔ)言結(jié)構(gòu)體結(jié)構(gòu)體偏移

2014-07-24 13:32:01

Google NowSiri

2025-05-14 03:00:00

2014-11-25 11:52:15

.NET

2015-03-26 09:23:17

天璣科技融合架構(gòu)

2021-05-20 09:11:00

5G5G網(wǎng)絡(luò)5G終端

2023-06-07 13:50:00

SaaS多租戶系統(tǒng)

2023-04-11 14:42:14

2015-11-02 09:43:25

ASP.NET異步編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)