4

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

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

附加信息:

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

  2. 我将使用实体框架核心

问题:

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

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

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

4

1 回答 1

4

回答上下文

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

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

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

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

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

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

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

有几种选择可以减轻可能出现的问题,或者至少限制东西破裂的可能性。一种是仅创建仅添加到当前模型的迁移。另一种方法是通过在两者之间设置一个异步通信层(如服务总线)来将数据库模型与应用程序分离。

这是一个相当复杂的定义策略,并且高度依赖于您正在构建的应用程序类型、数据库更新频率和数据库方案的复杂性等因素。

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

就我而言:如果您知道这即将到来,请立即采取行动。早期实施多租户是最容易的。越往前走,就越难,因为您可能会在应用程序中开始硬编码(不是真的,而是某种意义上的)连接,一旦您想添加多租户,就需要解耦这些连接。

结论

如果我正确解释了您的问题,您就知道多租户将成为您的应用程序的“事情”。这意味着您需要从一开始就解决它。但您不必从一开始就拥有完整的成熟多租户……您只需要为此做好准备

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

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

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

于 2019-09-23T15:28:19.327 回答