Azure SQL 多个弹性池(多租户 SaaS)

Azure SQL multiple Elastic Pools (Multi-Tenant SaaS)

假设我想使用 ASP.NET Core 创建一个多租户 SaaS 应用程序,并且我想使用类似于此示例的 Azure SQL 弹性池:Microsoft Docs

每个池的最大数据库数为 500:Azure Pricing

附加信息:

  1. 我将从 Azure SQL 单一数据库开始

  2. 我将使用 Entity Framework Core

问题:

  1. 如果我的应用超过 500 个用户会怎样?有哪些选择 有效地扩展这个? (当您达到弹性池的限制时)

  2. 该选项与 EF Core 迁移的匹配程度如何?

  3. 关于以后如何开始和处理这个问题还有其他建议吗?

回答上下文

在回答您的具体问题之前,让我添加一些关于我看到的解决方案的背景信息。多租户带来了租户管理。而且,就像您链接到的文档中一样,可能会有某种目录包含所有特定于租户的信息。其中一条信息可能(很可能会)是特定于租户的数据库的连接字符串。

想象一个租户连接,系统根据它是哪个租户(我们称之为租户上下文)从目录中获取要连接的数据库。应用程序会将连接字符串交给应用程序的其余部分进行处理。

下面是解决方案的妙处:连接字符串可以(几乎)指向任何地方。它可以指向池中的数据库,也可以指向托管实例。它甚至可以指向已通过 Internet 提供的本地数据库。这一切都是因为应用程序不知道数据在哪里,它只是获取一个连接字符串并开始工作。

1.如果我的应用超过 500 个用户会怎样?有哪些有效扩展的选项? (当您达到弹性池的限制时)

假设用户指的是租户:没有任何反应。新数据库在应用程序可访问的任何位置创建,例如在新池中。由于租户的连接字符串可以指向任何地方,这完全没问题。

2。该选项与 EF Core 迁移的匹配程度如何?

该选项既适用于 EF Core 迁移,也适用于任何其他数据库模型:对数据库的更新需要以适当且受管理的方式执行。例如,这可以通过 运行 迁移或 运行 更新脚本来完成。事实仍然存在:您需要更新多个数据库。为了实现这一点,制定一个体面的迁移计划是明智的。

有多种选择可以缓解可能出现的问题,或者至少可以限制破坏内容的可能性。一种是只创建只添加到当前模型的迁移。另一种方法是通过像服务总线一样在两者之间设置异步通信层来将数据库模型与应用程序分离。

这是一个定义起来相当复杂的策略,并且在很大程度上取决于您正在构建的应用程序类型、数据库更新频率以及数据库方案的复杂性等因素。

3。关于以后如何开始和处理这个问题还有其他建议吗?

就我而言:如果您知道这会发生,请立即行动。在早期实施多租户是最简单的。越往后越难,因为您可能会在您的应用程序中开始硬编码(不是真的,但有点)连接,一旦您想要添加多租户就需要解耦。

结论

如果我正确解释了您的问题,您就会知道多租户将成为您应用程序的 'thing'。这意味着您需要从一开始就解决它。但是您不必从一开始就拥有完全成熟的多租户......您只需要为此准备

获得更多技术性:例如,您可以实现一个 TenantContext,它在登录时识别租户并在登录时获取伴随的连接字符串(存储、服务总线、数据库等)。然后,在应用程序的其余部分,从 TenantContext 获取连接字符串并使用它们获取特定于租户的数据。

起初,例如在开发过程中,上下文可能非常简单,只有 return 一个租户的信息。但是由于您引入的解耦,应用程序的其余部分已经为多租户做好了准备。一旦对它的需求变得真实,您需要做的就是实施 TenantContext.

编辑:
由于下面的评论,作为补充: 一种预先在 DI 系统中注册 DbContext 实例的方法。您可以实现类似 ConnectionStringResolver 的东西,它被注入到上下文中。只要您确实需要 DbContext,租户上下文也是已知的。构造 DbContext,使用 ConnectionStringResolver 为租户找到正确的连接字符串。