无论体系结构以及用于实现它的组件如何,你都需要部署和配置解决方案的组件。 在多租户环境中,请务必考虑如何部署 Azure 资源,尤其是在为每个租户部署专用资源时,或是在基于系统中的租户数重新配置资源时。 在此页上,我们为解决方案架构师提供了有关部署多租户解决方案的指导,并演示了规划部署策略时要考虑的一些方法。
关键考虑因素和要求
在规划部署策略之前,需要清楚地了解要求,这十分重要。 具体注意事项包括:
- 预期规模:预期支持少量租户(如五个或更少)还是会增长到大量租户?
- 自动加入或受支持的加入:当租户准备好加入时,他们是否能够按照自动过程自行完成该过程? 或者,是否由新租户发起请求,你在收到请求后将他们手动加入? 团队是否需要手动审批步骤(例如用于防止滥用服务)?
- 预配时间:当租户准备好加入时,加入过程需要以多快的速度完成? 如果没有明确答案,请考虑是应以秒、分钟、小时还是天为单位进行度量。
- Azure 市场:是否计划使用Azure 市场启动部署? 如果这样做,则需要满足一些要求才能添加新租户。
还应考虑加入和预配步骤、自动化和资源管理责任。
加入和预配步骤
考虑加入租户时需要执行的所有操作,并记录此列表和工作流(即使手动执行也是如此)。 加入工作流通常包括以下内容:
- 接受商业协议。
- 收集为新租户配置系统所需的信息。
- 手动审批步骤(例如用于以防止欺诈或滥用服务)。
- 在 Azure 中预配资源。
- 创建或配置域名。
- 执行部署后配置任务,例如为租户创建第一个用户帐户并安全地将其凭据传输给租户。
- 手动配置更改,例如 DNS 记录更改。
清楚地记录加入新租户所需的工作流。
此外,请考虑需要为租户预配的特定 Azure 资源。 即使不为每个租户预配专用资源,也应考虑是否有时需要在加入新租户时部署资源。 当租户要求其数据存储在特定区域中,或者你接近解决方案中某个缩放单元或组件的限制,并且需要为下一批租户创建另一个实例时,可能会发生这种情况。
考虑加入过程是否可能会对其他租户造成中断,尤其是共享相同基础结构的用户。 例如,如果需要修改共享数据库,此过程是否会导致其他租户可能会注意到的性能影响? 考虑是否可以避免这些影响,或者通过在正常运行时间外执行加入过程来缓解这些影响。
自动化
对于云托管解决方案,始终建议进行自动部署。 使用多租户解决方案时,出于以下原因,部署自动化变得更加重要:
- 缩放:随着租户总体增加,手动部署过程会变得越来越复杂且耗时。 随着租户数量增长,自动化部署方法更容易进行缩放。
- 可重复:在多租户环境中,对所有租户使用一致的部署过程。 手动过程可能会产生错误,或是对某些租户而对其他租户不执行的步骤。 这些手动流程会使环境处于不一致状态,从而使团队更难管理解决方案。
- 中断的影响:与自动部署相比,手动部署发生中断的风险和可能性要大得多。 在多租户环境中,系统范围中断(由于部署错误)的影响可能很高,因为每个租户都可能会受到影响。
部署到多租户环境时,应使用部署管道,并使用基础结构即代码 (IaC) 技术,例如 Bicep、JSON ARM 模板、Terraform 或 Azure SDK。
如果计划通过 Azure 市场提供解决方案,则应为新租户提供完全自动加入过程。 SaaS 履行 API 文档中介绍了此过程。
最大资源容量
以编程方式将租户资源部署到共享资源时,请考虑每个资源的容量限制。 当接近该限制时,可能需要创建资源的另一个实例以支持进一步缩放。 请考虑部署的每个资源的限制,以及将触发部署另一个实例的条件。
例如,假设解决方案包含 Azure SQL 逻辑服务器,并且解决方案会为每个租户在该服务器上预配专用数据库。 单一逻辑服务器具有限制,其中包括逻辑服务器支持的最大数据库数。 在接近这些限制时,可能需要预配新服务器,以便可以继续加入租户。 请考虑是自动执行此过程还是手动监视增长。
资源管理责任
在某些多租户解决方案中,会为每个租户部署专用 Azure 资源,例如每个租户的数据库。 或者,你可能会决定在单个资源实例上容纳一定数量的租户,因此你拥有的租户数决定了部署到Azure 的资源集。 在其他解决方案中,你会部署单个共享资源集,然后在加入新租户时重新配置资源。
其中每个模型都需要以不同方式部署和管理资源,并且必须考虑如何部署和管理预配的资源的生命周期。 两种常用方法如下所示:
- 将租户视为所部署的资源的配置,并使用部署管道部署和配置这些资源。
- 将租户视为数据,并让控制平面为租户预配和配置基础结构。
下面提供了对这些方法的进一步讨论。
测试
计划在每个部署期间和之后彻底测试解决方案。 可以使用自动测试来验证解决方案的功能和非功能行为。 确保测试租户隔离模型,考虑使用 Azure Chaos Studio 等工具故意引入模拟实际中断的故障,并验证是否即使在组件不可用或发生故障时,解决方案也可正常运行。
要考虑的方法和模式
来自 Azure 体系结构中心和更广泛社区的多个设计模式与多租户解决方案的部署和配置相关。
部署戳模式
部署缩放单元模式涉及为单个租户或一组租户部署专用基础结构。 单个缩放单元可能包含多个租户,或者可能专用于单个租户。 可以选择部署单个缩放单元,也可以跨多个缩放单元协调部署。 如果为每个租户部署专用缩放单元,还可以考虑以编程方式部署整个缩放单元。
部署环
部署环使你可以在不同时间向不同基础结构组推出更新。 此方法通常与部署缩放单元模式结合使用,并根据租户首选项、工作负载类型和其他注意事项将缩放单元组分配给不同的环。 有关详细信息,请参阅部署环。
特性标志
功能标志使你可以逐步向不同租户公开解决方案的新功能或版本,同时维护单个代码库。 请考虑使用 Azure 应用程序配置管理功能标志。 有关详细信息,请参阅功能标志。
有时需要选择性地为某些客户启用特定功能。 例如,你可能具有允许访问特定功能的不同定价层。 功能标志通常不是这些方案的正确选择。 相反,请考虑构建一个过程来跟踪并强制实施每个客户拥有的许可证权利。
要避免的反模式
部署和配置多租户解决方案时,请务必避免使你无法缩放的情况。 这些演示包括以下内容:
- 手动部署和测试。 如上所述,手动部署过程会增加风险,并减慢部署能力。 请考虑使用管道进行自动部署,以编程方式从你的解决方案代码中创建资源,或将两者结合使用。
- 专用的租户自定义。 避免部署仅适用于单个租户的功能或配置。 此方法向部署和测试过程增添了复杂性。 请改为对每个租户使用相同的资源类型和代码库,并将功能标志等策略用于临时更改或逐步推出的功能,或者使用不同的定价层及许可证权利来选择性地为需要它们的租户启用功能。 即使对于具有隔离资源或专用资源的租户,也可以使用一致的自动部署过程。
租户列表作为配置或数据
在多租户解决方案中部署资源时,可以考虑以下两种方法:
- 使用自动部署管道部署每个资源。 添加新租户时,重新配置管道,以便为每个租户预配资源。
- 使用自动部署管道部署不依赖于租户数的共享资源。 对于为每个租户部署的资源,请在应用程序中创建它们。
考虑这两种方法时,应区分将租户列表视为配置还是数据。 考虑如何为系统生成控制平面时,这种区别也很重要。
租户列表作为配置
将租户列表视为配置时,可从集中式部署管道部署所有资源。 加入新租户时,会重新配置管道或其参数。 通常,重新配置通过手动更改来进行,如下图所示。
加入新租户的过程可能类似于下面这样:
- 更新租户列表。 这通常是通过配置管道本身或通过修改管道配置中包含的参数文件来手动进行。
- 触发管道运行。
- 管道会重新部署完整 Azure 资源集,包括任何特定于新租户的资源。
此方法往往适用于少量租户,以及共享所有资源的体系结构。 这是一个简单方法,因为可以使用单个过程部署和配置所有 Azure 资源。
但是,如果你接近大量租户(例如 5 到 10 个或更多),添加租户时重新配置管道会变得繁琐。 运行部署管道所需的时间通常也会显著增加。 此方法也不容易支持自助租户创建,并且租户加入前的提前期可能较长,因为需要触发管道运行。
租户列表作为数据
将租户列表视为数据时,仍使用管道部署共享组件。 但是,对于需要为每个租户部署的资源和配置设置,以命令方式部署或配置资源。 例如,控制平面可以使用 Azure SDK 创建特定资源或启动参数化模板的部署。
加入新租户的过程可能类似于下面这样,会异步进行:
- 请求加入租户,例如通过向系统控制平面发起 API 请求。
- 工作流组件接收创建请求并协调剩余步骤。
- 工作流开始将特定于租户的资源部署到 Azure。 这可以通过使用命令性编程模型(例如使用 Azure SDK)或以命令方式触发 Bicep 或 Terraform 模板的部署来实现。
- 部署完成后,工作流会将新租户的详细信息保存到中央租户目录中。 为每个租户存储的数据可能包括租户 ID 以及工作流创建的所有特定于租户的资源的资源 ID。
通过执行此操作,可以为新租户预配资源,而无需重新部署整个解决方案。 为每个租户预配新资源涉及的时间可能较短,因为只需要部署这些资源。
但是,此方法通常需要花费更多的时间来构建,并且需要根据租户数或你需要满足的预配时间范围来证明你所花费的工作量。
有关此方法的详细信息,请参阅多租户控制平面的注意事项。
注意
Azure 部署和配置操作通常需要一段时间才能完成。 确保使用适当的过程启动和监视这些长时间运行的操作。 例如,可以考虑遵循异步请求-答复模式。 使用旨在支持长时间运行的操作的技术,例如 Azure 逻辑应用和 Durable Functions。
示例
Contoso 为其客户运行多租户解决方案。 目前,他们拥有 6 个租户,预计在未来 18 个月内会增长到 300 个租户。 Contoso 遵循每个租户各有专用数据库的多租户应用。 他们部署了单个应用服务资源集以及一个在所有租户之间共享的 Azure SQL 逻辑服务器,并为每个租户部署专用 Azure SQL 数据库,如下图所示。
Contoso 使用 Bicep 部署其 Azure 资源。
选项 1 - 对所有内容使用部署管道
Contoso 可能考虑使用部署管道部署其所有资源。 其管道会部署包含其所有 Azure 资源(包括每个租户的 Azure SQL 数据库)的 Bicep 文件。 参数文件定义租户列表,Bicep 文件使用 资源循环为每个列出的租户部署数据库,如下图所示。
如果 Contoso 遵循此模型,则需要在加入新租户的过程中更新其参数文件。 然后需要重新运行管道。 此外,他们需要手动跟踪是否接近任何限制,例如他们是否以意外的高速率增长,并接近单个 Azure SQL 逻辑服务器上支持的最大数据库数。
选项 2 - 使用部署管道和命令性资源创建的组合
或者,Contoso 可能会考虑分离 Azure 部署的责任。
Contoso 使用 Bicep 文件来定义应部署的共享资源。 共享资源支持其所有租户,并包含租户映射数据库,如下图所示。
然后,Contoso 团队可以构建一个包含租户加入 API 的控制平面。 当销售团队完成向新客户的销售时,Microsoft Dynamics 会触发 API 开始加入过程。 Contoso 还提供自助服务 Web 界面供客户使用,该界面会触发 API。
API 会异步启动加入新租户的工作流。 该工作流会启动新 Azure SQL 数据库的部署,这可以通过以下方法之一来完成:
- 使用 Azure SDK 启动定义 Azure SQL 数据库的第二个 Bicep 文件的部署。
- 使用 Azure SDK 通过管理库以命令方式创建 Azure SQL 数据库。
部署数据库后,工作流会将租户添加到租户列表数据库,如下图所示。
正在进行的数据库架构更新由其应用层启动。
作者
本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。
主要作者:
- John Downs | 首席软件工程师
其他参与者:
- Bohdan Cherchyk | FastTrack for Azure 高级客户工程师
- 阿森·弗拉基米尔斯基|首席工程师,FastTrack for Azure
若要查看非公开的 LinkedIn 个人资料,请登录到 LinkedIn。