在線文檔:http://doc.yc-l.com/#/README
在線演示地址:http://yc.yc-l.com/#/login
源碼github:https://github.com/linbin524/yc.boilerplate
源碼gitee:https://gitee.com/linxuanming/yc.boilerplate
元磁之力框架技術群QQ:1060819005
視頻教程:
- 元磁之力框架開源初心和框架設計介紹(上): https://www.bilibili.com/video/BV1VM4y1G7hC/
- 元磁之力框架開源初心和框架設計介紹(下): https://www.bilibili.com/video/BV15h411s7w6/
- 元磁之力框架數據庫表和代碼生成使用教程實戰: https://www.bilibili.com/video/BV1oM4y137D5/
多租戶設計
SaaS介紹
SaaS 是 Software-as-a-Service(軟件即服務)的簡稱,隨着互聯網技術的發展和應用軟件的成熟, 在 21 世紀開始興起的一種完全創新的軟件應用模式。它與“on-demand software”,the application service provider(ASP,應用服務提供商),hosted software(托管軟件)所具有相似的含義。
它是一種通過 Internet 提供軟件的模式,廠商將應用軟件統一部署在自己的服務器上,客戶可以根據自己實際需求,通過互聯網向廠商定購所需的應用軟件服務,按定購的服務多少和時間長短向廠商支付費用,並通過互聯網獲得廠商提供的服務。用戶不用再購買軟件,而改用向提供商租用基於 Web 的軟件,來管理企業經營活動,且無需對軟件進行維護,服務提供商會全權管理和維護軟件,軟件廠商在向客戶提供互聯網應用的同時,也提供軟件的離線操作和本地數據存儲,讓用戶隨時隨地都可以使用其定購的軟件和服務。
對於許多小型企業來說,SaaS 是采用先進技術的最好途徑,它消除了企業購買、構建和維護基礎設施和應用程序的需要。
多租戶介紹
多租戶技術或稱多重租賃技術,簡稱 SaaS,是一種軟件架構技術,是實現如何在多用戶環境下(此處的多用戶一般是面向企業用戶)共用相同的系統或程序組件,並且可確保各用戶間數據的隔離性。
簡單講:在一台服務器上運行單個應用實例,它為多個租戶(客戶)提供服務。從定義中我們可以理解:多租戶是一種架構,目的是為了讓多用戶環境下使用同一套程序,且保證用戶間數據隔離。那么重點就很淺顯易懂了,多租戶的重點就是同一套程序下實現多用戶數據的隔離。
本框架多租戶設計方案
獨立數據庫(基於 Database 的方式)
這是第一種方案,即一個租戶一個數據庫,這種方案的用戶數據隔離級別最高,安全性最好,但成本較高。
優點: 為不同的租戶提供獨立的數據庫,有助於簡化數據模型的擴展設計,滿足不同租戶的獨特需求;如果出現故障,恢復數據比較簡單。
缺點: 增多了數據庫的安裝數量,隨之帶來維護成本和購置成本的增加。 這種方案與傳統的一個客戶、一套數據、一套部署類似,差別只在於軟件統一部署在運營商那里。如果面對的是銀行、醫院等需要非常高數據隔離級別的租戶,可以選擇這種模式,提高租用的定價。如果定價較低,產品走低價路線,這種方案一般對運營商來說是無法承受的。
作者設計意圖:SaaS 模式平台化設計,從分庫角度,可以有效的解決耦合度問題;在運維上考量,避免了牽一發而動全身的風險。
共享數據庫,共享 Schema (基於 TenantId 的方式)
共享數據表,即租戶共享同一個 Database、同一個 Schema,但在表中增加 TenantId 多租戶的數據字段。這是共享程度最高、隔離級別最低的模式。 即每插入一條數據時都需要有一個客戶的標識。這樣才能在同一張表中區分出不同客戶的數據。
優點: 兩種方案比較,方案的維護和購置成本最低,允許每個數據庫支持的租戶數量最多。
缺點: 隔離級別最低,安全性最低,需要在設計開發時加大對安全的開發量; 數據備份和恢復最困難,需要逐表逐條備份和還原。
PS:該方案雖然在框架中預留了每個數據表對應 Entity 都有一個TenantId字段,但本框架目前采用 獨立分庫實現多租戶,需要共享庫的網友,可以在業務層自己區分。
多租戶使用
框架定義了租戶接口 ITenant,並實現了默認租戶邏輯:DefaultTenant,使用者可以自定義實現租戶邏輯,在相關的注入模塊修改,
CustomAutofacModule.cs 注入模塊進行相關配置。
//多租戶注入
builder.RegisterType<DefaultTenant>().As<ITenant>().AsImplementedInterfaces().InstancePerLifetimeScope().PropertiesAutowired();
