.NET Core 中采用獨立數據庫的SAAS(多租戶)方法

介紹

多租戶是指一種軟件架構,其中軟件的單個實例在服務器上運行并為多個租戶提供服務。

在基于 SAAS 的平臺中,租戶是指使用該平臺開展業務運營的客戶。每個租戶都擁有獨立的數據、用戶帳戶和配置設置,并且與其他租戶隔離。

多租戶允許有效利用資源,因為同一個軟件實例可以為多個客戶提供服務,從而減少了為每個客戶提供單獨服務器和基礎設施的需求。

它還可以更輕松地進行維護和更新,因為可以對軟件的單個實例進行更改,而不必為每個客戶更新多個實例。

不同的實施方案

我們可以將多租戶實現分為三種不同的方法。

單一數據庫

所有租戶共享一個數據庫實例和架構。這種方法最節省資源,跨租戶的數據分析也變得更加簡單。這是一種經濟高效的方法,并簡化了管理。

但這種方法的安全性成為一個關鍵問題;隨著租戶數量的增加,出現性能瓶頸的可能性也會增大。數據法規的合規性,尤其是當租戶在不同地區運營且數據保護法規各異時,管理起來會變得復雜且具有挑戰性。

具有單獨模式的單一數據庫

所有租戶將共享單個數據庫,但每個租戶將擁有各自的架構。這種方法比單獨的數據庫更節省資源,同時仍然提供高級別的隔離和安全性。管理單個數據庫可以降低運營成本,例如備份和更新等管理任務。

然而,在資源爭用程度較高的場景中,例如跨不同模式的頻繁讀寫操作,可能會出現數據爭用和性能下降。

獨立數據庫

每個租戶都將擁有自己的數據庫,并且應用程序將有一個通用數據庫來存儲特定于租戶的信息。多個數據庫可提供更強的安全性和隔離性,從而降低租戶之間數據泄露和未經授權訪問的風險。

可擴展性得到增強,因為每個租戶的數據庫都可以根據各自的需求和使用模式獨立擴展。

然而,管理多個數據庫會增加管理任務的復雜性,可能會出現同步挑戰,導致不同數據庫之間數據不一致。此外,存儲、處理和基礎設施成本方面的資源消耗也會更高。

今天,在本博客中,我們將學習如何在 .Net Core 應用程序中實現多租戶的單獨數據庫方法以及如何向 DbContext 提供動態連接字符串。

我將給出一個應用程序的演示,其中我將采用兩個 DbContext 類。

? ? ? ? 1、一個用于主數據庫的 DB Context,它將存儲與租戶相關的內容,例如租戶詳細信息、租戶用戶登錄等。

? ? ? ? 2、每個租戶數據庫的第二個數據庫上下文,我們將根據 TenantId 連接該數據庫

我們將添加一個名為 x-tenant-id 的請求標頭,其中將包含我們想要獲取數據的租戶 ID。

步驟 1

創建租戶 Pod 表。我們可以使用此表存儲數據庫的租戶連接字符串。如果我們不想將連接字符串直接存儲在數據庫中,可以使用 Azure Key Vault 或 AWS Secret Manager,并在該數據庫中存儲 Secret 名稱。

// Tenant.cs
[Table("tenants")]
public class Tenant
{
[Key]
public Guid Id { get; protected set; }
public string Name { get; protected set; }
public Tenant(Guid id, string name)
{
Id = id;
Name = name;
}
}

// TenantPod.cs
[Table("tenant_pods")]
public class TenantPod
{
[Key]
public Guid Id { get; protected set; }
public Guid TenantId { get; protected set; }
public string ConnectionString { get; protected set; }
[ForeignKey(nameof(TenantId))]
public virtual Tenant Tenant { get; protected set; }
public TenantPod(Guid id, Guid tenantId, string connectionString)
{
Id = id;
TenantId = tenantId;
ConnectionString = connectionString;
}
}

步驟2

創建一個方法,根據請求標頭獲取連接字符串。

// TenantsService.cs
public interface ITenantsService
{
string GetConnectionByTenant();
}

public class TenantsService: ITenantsService
{
private readonly HttpContext? _httpContext;
public TenantsService(IHttpContextAccessor httpContextAccessor)
{
_httpContext = httpContextAccessor.HttpContext;
}
public string GetConnectionByTenant()
{
var tenantId = Guid.Empty;
try
{
if (_httpContext == null)
throw new Exception("Tenant Not Found");

? ? ? ? ? ? var clientId = _httpContext.Request.Headers["x-tenant_id"];
if (string.IsNullOrEmpty(clientId))
{
throw new Exception("Tenant Request Header is missing.");
}
Guid.TryParse(clientId.ToString(), out tenantId);
// Logic to get DB connection based on tenant
// Dummy Connection string Her you should have your logic to get connection string and return it
return "Server=127.0.0.1;Database=multiDemoMain;Port=5432;User Id=postgres;Password=123456";
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}
}

步驟3

在Db Context中,添加邏輯以使用上述方法,覆蓋DBContext類的OnConfiguring方法。

// MultiTenantDbContext.cs
public class MultiTenantDbContext : DbContext
{
private readonly ITenantsService _tenantsService;
public MultiTenantDbContext(DbContextOptions<MultiTenantDbContext> options, ITenantsService tenantsService) :
base(options)
{
_tenantsService = tenantsService;
}
public DbSet<Tenant> Tenants { get; set; }
public DbSet<Document> Documents { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connectionString = _tenantsService.GetConnectionByTenant();
if (string.IsNullOrEmpty(connectionString))
{
throw new Exception("Tenant Connection Not found");
}
optionsBuilder.EnableSensitiveDataLogging();
optionsBuilder.UseNpgsql(connectionString, b =>
{
b.SetPostgresVersion(new Version(9, 6));
b.EnableRetryOnFailure(10, TimeSpan.FromSeconds(30), null);
b.CommandTimeout(300);
});
optionsBuilder.UseNpgsql(connectionString).UseSnakeCaseNamingConvention();
}
}

就是這樣。現在,您可以在存儲庫或服務層中使用此數據庫上下文,并且此 DbContext 將根據傳遞的 TenantId 獲取連接字符串。我們需要確保每個 API 的請求標頭中都有一個租戶。

注意:在本例中,我有一個在兩個數據庫中都重復的租戶表,但要使用約束,我們需要復制該表,并且應該有邏輯來同步數據庫中的數據。此外,我們可以實現 Redis 緩存或內存緩存服務來從內存中獲取連接字符串,從而加快速度。在我的下一篇文章中,我們將學習如何在 .Net Core 中使用內存緩存和 Redis 緩存。

結論

在本文中,我們了解了多租戶及其不同的實現方式。此外,我們還探索了如何基于 TenantId 動態連接數據庫。

如果您喜歡此文章,請收藏、點贊、評論,謝謝,祝您快樂每一天。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94299.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94299.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94299.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

運維日常工作100條

這是一份非常詳細和實用的“運維日常工作100條”清單。它涵蓋了從日常巡檢、變更管理、故障處理到安全、優化和文檔等運維工作的方方面面,可以作為運維工程師的日常工作指南和檢查清單。 運維日常工作100條 一、日常巡檢與監控 (20條) 檢查核心監控大盤:查看整體業務健康狀態…

OpenHarmony子系統介紹

OpenHarmony子系統OpenHarmony子系統1. AI業務子系統2. 方舟運行時子系統3. ArkUI框架子系統4. DFX子系統5. DeviceProfile子系統6. XTS子系統7. 上傳下載子系統8. 主題框架子系統9. 事件通知子系統10. 位置服務子系統11. 元能力子系統12. 全局資源調度子系統13. 全球化子系統1…

博士招生 | 英國謝菲爾德大學 招收計算機博士

內容源自“圖靈學術博研社”gongzhonghao學校簡介謝菲爾德大學&#xff08;The University of Sheffield&#xff09;是英國久負盛名的公立研究型大學&#xff0c;也是羅素集團成員之一。在 2026 年 QS 世界大學排名中&#xff0c;謝菲爾德大學位列第92位&#xff0c;其中計算機…

如何理解面向過程和面向對象,舉例說明一下?

面向過程和面向對象是兩種不同的編程思想&#xff0c;核心區別在于解決問題的視角不同&#xff1a;前者關注 “步驟和過程”&#xff0c;后者關注 “對象和交互”。面向過程的核心思想是把問題拆解成一系列步驟&#xff0c;通過函數實現每個步驟&#xff0c;然后按順序調用這些…

深入了解評估與微調中使用的Graders:原理、實現與最佳實踐

深入了解評估與微調中使用的Graders 在模型評估與微調&#xff08;Fine-tuning&#xff09;過程中&#xff0c;Graders&#xff08;評分器&#xff09;是衡量模型輸出與參考答案之間表現的重要工具。本文將系統介紹Grader的類型、技術實現及如何在實際項目中融入穩定且高質量的…

行緩存(line buffer)在圖像卷積中的工作方式

上面這張圖配合文字&#xff0c;展示了行緩存&#xff08;line buffer&#xff09;在圖像卷積中的工作方式&#xff1a;上半部分是一個按行掃描輸入的圖像塊&#xff08;示例為 99&#xff0c;編號 1–81&#xff09;。 藍色表示已被寫入行緩存并按隊列等待的數據&#xff0c;綠…

【數據分享】中國371個城市的坡度矢量數據和excel數據

今天要說明數據就是中國371個城市的坡度矢量數據和excel數據。數據介紹在城市發展的進程中&#xff0c;地形地貌始終是影響規劃決策的關鍵因素&#xff0c;而坡度作為表征地表傾斜程度的核心指標&#xff0c;更是貫穿于城市建設、生態保護等諸多環節。本文將全面解讀中國 371 個…

《WINDOWS 環境下32位匯編語言程序設計》第7章 圖形操作(1)

圖形設備接口GDI&#xff08;Graphics Device Interface&#xff09;是Win32的一個重要組成部分&#xff0c;其作用是允許Windows的應用程序將圖形輸出到計算機屏幕、打印機或其他輸出設備上。GDI實際上是一個函數庫&#xff0c;包括直線、畫圖和字體處理等數百個函數。7.1 GDI…

數據結構-HashMap

在 Java 鍵值對&#xff08;Key-Value&#xff09;集合中&#xff0c;HashMap 是使用頻率最高的實現類之一&#xff0c;憑借高效的查找、插入性能&#xff0c;成為日常開發的 “利器”。本文將從 HashMap 的底層原理、核心特點、常用方法到遍歷方式、使用注意事項&#xff0c;進…

[系統架構設計師]安全架構設計理論與實踐(十八)

[系統架構設計師]安全架構設計理論與實踐&#xff08;十八&#xff09; 一.信息安全面臨的威脅 1.信息系統安全威脅的來源 物理環境&#xff0c;通信鏈路&#xff0c;網絡系統&#xff0c;操作系統&#xff0c;應用系統&#xff0c;管理系統 2.網絡與信息安全風險類別 風險類別…

AI適老服務暖人心:AI適老機頂盒破數字鴻溝、毫米波雷達護獨居安全,銀發生活新保障

銀發經濟領域長期受限于 “專業照護資源稀缺”“老年人數字適應能力弱”“獨居老人安全隱患多” 的困境&#xff0c;而 AI 技術的適老化改造&#xff0c;正讓銀發服務從 “被動保障” 轉向 “主動關懷”&#xff0c;既能幫老年人跨越數字鴻溝&#xff0c;又能為獨居老人筑起安全…

Linux應用軟件編程---網絡編程1(目的、網絡協議、網絡配置、UDP編程流程)

Linux下的網絡編程一、目的不同主機&#xff0c;進程間通信。二、解決的問題1. 主機與主機之間物理層面必須互聯互通。 2. 進程與進程在軟件層面必須互聯互通。物理層面的互聯互通流程圖如下&#xff1a;其中&#xff1a;IP地址&#xff1a;計算機的軟件地址&#xff0c;用來標…

常見開源協議詳解:哪些行為被允許?哪些被限制?

常見開源協議詳解&#xff1a;哪些行為被允許&#xff1f;哪些被限制&#xff1f; 開源世界的魅力在于共享與合作&#xff0c;但不同的開源協議對分發、修改、再發布以及宣傳/推廣有不同的要求和限制。很多開發者在 fork 項目、改 README、放到自己倉庫并在自媒體傳播 時&…

服務器硬盤進行分區和掛載

查看服務器上的硬盤&#xff1a;lsblk -d -o NAME,SIZE,MODEL可以看到我的硬盤是除了vda系統盤以外&#xff0c;還有個vdb。我們查看一下分區&#xff1a;lsblk可以看到&#xff1a;vdb 1T disk &#xff08;底下沒有分區&#xff0c;也沒有掛載&#xff09;我們想要用起來這…

【C初階】數據在內存中的存儲

目錄 1. 整數在內存中的存儲 2. 大小端字節序 2.1 什么是大小端&#xff1f; 2.2 為什么有大小端&#xff1f; 2.3 練習 2.3.1 練習1 2.3.2 練習2 2.3.3 練習3 2.3.4 練習4 2.3.5 練習5 2.3.6 練習6 3. 浮點數在內存中的存儲 3.1 浮點數存儲的過程 3.2 浮點數的取…

AI 自動化編程 trae 體驗2 幫我分析一個項目

總結&#xff1a; 接手一個項目可以讓trae 幫忙分析 上次講到trae在處理組件引入的時候&#xff0c;經常會碰到版本問題&#xff0c;分析引入了互聯網上非本版本或者有bug的代碼。主要依賴互聯網的資源庫。 但是分析一個項目應該是沒問題。 這次表現非常好&#xff0c;接手一個…

VMware虛擬機中CentOS 7 報錯 ping: www.xxx.com: Name or service not known

1:主要原因是網絡配置的問題 2:其實就是下面三張圖片中的,物理機虛擬網卡 vmware8 和虛擬機網絡編輯器&#xff0c;如果設置靜態IP 就是這三個地方的問題最簡單的解決辦法第一步&#xff1a;還原虛擬機網絡點擊確認后 ** 第二步給自己的虛擬機設置網絡連接方式 選擇NAT模式連接…

Java面試-自動裝箱與拆箱機制解析

&#x1f44b; 歡迎閱讀《Java面試200問》系列博客&#xff01; &#x1f680;大家好&#xff0c;我是Jinkxs&#xff0c;一名熱愛Java、深耕技術一線的開發者。在準備和參與了數十場Java面試后&#xff0c;我深知面試不僅是對知識的考察&#xff0c;更是對理解深度與表達能力的…

《VMware 安裝 CentOS 7.9 虛擬機詳細教程(含圖解步驟)》

目錄1.安裝前準備1.1 準備VMware軟件1.1.1 方式一1.1.2 方式二1.2 準備centos7.9鏡像1.2.1 方式一1.2.2 方式二2.安裝centos7.91.安裝前準備 1.1 準備VMware軟件 VMware需要的激活碼百度直接搜索vmware workstation17激活碼就可以搜索到 1.1.1 方式一 這種方式需要注冊官網的…

新能源知識庫(84)什么是IEC白皮書

IEC白皮書是由國際電工委員會&#xff08;IEC&#xff09;發布的戰略性技術文件&#xff0c;旨在針對新興技術和社會發展趨勢&#xff0c;提出標準化需求和發展路徑&#xff0c;為全球產業提供前瞻性指導。在新能源領域&#xff0c;IEC白皮書是推動技術創新、產業協同和國際規則…