我的书单

概述

在上一章中,我们探索控制平面,探讨了注册和身份验证在实现多租户架构中的更广泛作用。在此过程中,简要介绍了租户管理服务如何用于将新租户引入系统。现在,我们将深入探讨该服务,更好地理解其内部工作原理,并全面考察其职责范围。这将帮助您更好地掌握支撑租户管理的核心数据、操作和构造,从而在配置租户架构的各个方面以及管理关键租户事件的生命周期时,将租户管理置于核心位置。

我们将从构建租户管理服务的基础开始,探讨其核心设计和实现的要素。在此过程中,我将介绍该服务管理的常见租户属性。您会发现,存储和管理这些属性大多较为直观。然而,您选择存储的内容可能对下游产生其他影响,从而扩展其在整个SaaS架构中的角色和应用范围。为了更好地理解租户管理的整体角色和体验,我们还需探讨如何实现对租户的管理。我们将分析这可以通过API或系统管理控制台来实现。在此过程中,您将获得另一个视角,了解租户管理服务如何融入控制平面体验。我们将探讨如何利用租户管理服务创建对环境的运营视图,从而管理系统中租户的状态。

租户管理的另一个维度是租户生命周期管理。目标是超越租户的初始配置,考察可能影响租户状态的各种事件。租户从活跃状态转变为非活跃状态意味着什么?您的系统如何处理此类状态变化?

如何管理并执行租户从一个层级迁移到另一个层级的操作?其他系统(例如计费系统)的状态如何传递给您的租户管理服务?这些都是可能与租户管理产生交互的领域,并且可能对您SaaS架构的不同层级产生连锁影响。本章的重点是突出租户管理的这些细节,并帮助您更好地理解影响解决方案中多租户策略和模式的考虑因素。

租户管理基础

为了更好地理解租户管理的范围和性质,让我们先看看租户管理宇宙中的核心组成部分。图5-1提供了一个概念视图,展示了通常构成整体租户管理范围的各种元素。

图5-1 租户管理的影响范围

您将看到,我将租户管理放在了图表的中心,并标识了通常通过与租户的连接进行配置或管理的区域。在顶部,我表示了一些可能通常与租户管理服务交互的区域。这里的关键参与者是入驻,它对租户管理有重大影响。每次创建租户时,都会触发与新租户相关的许多不同资源的配置和设置。您还会看到,我放置了停用和计费,这两个部分在租户经历其生命周期的不同阶段(更改层级、停用等)时都会与租户管理有关联。

在图5-1的右侧,您会看到通过租户管理服务管理和配置的两种不同类型的数据。在此分类中,我将这些数据标记为“核心租户属性”。这些属性代表了大多数租户所需的核心基础数据,包括租户标识符、状态(启用/禁用)、层级、公司名称、入驻状态、最后活跃日期等。我还显示了一个单独的占位符用于身份设置。这些设置存储了可以通过租户管理服务配置的不同租户身份验证属性。这里是多因素身份验证(MFA)、密码策略、身份提供商映射及其他身份相关设置的存储位置。路由策略配置也位于此处。此处存储的配置数据用于捕获任何用于确定租户如何路由到基础设施不同部分的租户特定设置。例如,URL可能出现在此处。

在图5-1的左侧,我展示了密钥和密钥的配置。这些设置用于配置环境中的不同安全方面。例如,您可能有按租户管理的密钥或加密密钥。对于某些环境,这些设置的管理在整体隔离和安全配置文件中可能发挥更重要的作用。

最后,在图5-1的底部,展示了可以与租户关联的不同用户类型。我展示了租户管理员和几个租户用户,以说明租户与可能与该租户关联的各种用户之间的关系。租户管理员在租户首次创建时生成。然而,在完成入驻后,租户还可以为其系统创建其他用户,包括其他租户管理员。这些用户都逻辑上与一个租户相关联。对租户配置的任何更改都将应用于所有这些用户。

构建租户管理服务

让我们从租户管理的概念视角及其作用,转向实际实现租户管理服务的内容。该服务的接口通常被划分为两个逻辑类别。首先,有一系列专注于配置数据基本管理的操作。这些操作通常通过创建、读取、更新和删除(CRUD)接口暴露。另一类操作则围绕更广泛的租户管理操作(如租户停用、租户退役等)。这些操作通常对租户管理服务的整体复杂性贡献最大。

图5-2展示了一个示例租户管理服务的组成部分。我在此试图提供一个概念视图,展示该服务可能包含的常见接口和用户体验。左侧列出了所有入口点,与之前提到的摘要相对应。顶部功能集负责配置管理,底部入口点则支持各种管理相关操作。

图5-2 租户管理服务的示例实现

该图的右侧突出了您在租户管理体验中将涉及的各种后端资源和集成。在右上角,我展示了一些存储选项。在此示例中,我选择使用NoSQL存储(DynamoDB)来存储租户配置信息。通常,此类数据的大小和消费模式与无模式存储模型非常匹配。这还使得在不需更新模式或迁移数据的情况下,轻松对租户配置结构进行更改。

我还在此处放置了占位符,以代表可能包含在租户管理服务中的部分租户生命周期组件。我将在后续内容中详细介绍这些生命周期概念,但在此先展示以明确该服务可能需要支持租户退役、层级迁移及其他租户生命周期事件。这些组件可能需要根据操作性质进行不同程度的基础设施配置、预配置或移除。这通常意味着需要调用与这些操作事件关联的基础设施自动化脚本或代码。我将这些概念通过队列集成展示,仅为突出实际处理这些事件的工作可能由事件触发,并作为异步任务的一部分执行。

最后一个我添加的组件是计费。您的服务可能与控制平面的计费服务(或直接与计费提供商)有多个集成。计费系统可能触发事件以更新租户的状态。或者,租户管理服务可能触发事件,最终向计费服务发送请求。

您可以看出,租户管理服务本身并不会为您的控制平面引入显著的复杂性。同时,它位于管理租户状态关键要素的核心位置,这些要素直接影响多租户架构的实现和行为。此外,它还为处理租户生命周期事件提供了集中化的处理中心。

生成租户标识符

在租户管理服务的实现中,您需要负责生成代表系统中任何租户的通用唯一标识符。租户标识符最常用的机制是全局唯一标识符(GUID)。它提供了一种自然的方式,确保值在全球范围内唯一且不依赖于租户的其他属性。此处的目标有两点。首先,您需要一个独立且不可变的值,能够在多租户环境中普遍代表您的租户。其次,您需要确保任何其他使用此标识符的组件无法将其映射回系统中的特定租户或实体。此标识符提供了一种在不暴露租户任何具体信息的情况下表示租户的方式。

需要注意的是,某些多租户环境可能包含其他更友好的租户识别方式。例如,如果系统为每个租户使用子域名或自定义域名,则需要一种方式将该实体名称映射到租户标识符。在此情况下,我可能拥有mycompany.saasprovider.com,其中“mycompany”子域名代表一个对外展示的名称,该名称随后会被映射到内部租户标识符。即使你在系统入口处使用了其他名称,这些实体名称或引用也不应被视为租户标识符。将它们分开有其合理原因。其中最明显的原因是需要确保可以更改这些友好名称而不影响系统其他部分。这与数据管理的基本原则一致,正是这些原则促使人们使用GUID来标识数据库中的不同项。

存储基础设施配置

除了存储基本租户属性外,租户管理还可以用于存储租户特定的基础设施配置信息。根据您的多租户应用程序的部署模型,您可能需要将身份配置、路由模式和其他基础设施选项存储并由租户管理服务进行管理。此类数据通常不会直接由管理界面进行管理。相反,这些数据会在多租户基础设施配置过程中存储在此处,随后被应用程序中需要此信息来配置或解析环境中租户映射的各个组件引用。

您最终存储在此处的数据由您的SaaS架构的具体实现决定。例如,如果您为每个租户使用独立的身份构造,可能需要通过租户管理服务存储租户与其身份构造的映射关系。如果您拥有隔离的租户环境,且存在指向租户特定入口点或URL的映射,这些映射可由租户管理服务存储。这些只是部分示例。关键在于,租户管理可能管理超出基本租户属性范围的数据。

虽然租户管理服务是存储租户状态和配置的理想集中式位置,但您必须确保该服务不会成为系统瓶颈。如果存储在此处的数据被系统中各个组件频繁访问,您需要考虑替代策略来管理和访问这些数据。理想情况下,此处的状态不应被应用程序的服务大量使用。这就是为什么我们将关键租户属性放入JWT中,以减少您需要不断返回单一集中式服务来获取此上下文的频率。

租户配置管理

租户管理初期的大部分关注点在于其在创建和配置租户作为入驻流程的一部分所发挥的作用。需要特别指出的是,租户管理的作用并不仅限于入驻阶段。该服务在租户生命周期中还用于支持各种运营场景和使用案例。为了更好地理解这一点,让我们回到第4章中提到的系统管理控制台。该控制台提供了一个管理视图,用于查看、配置和管理您的多租户环境(参见图5-3)。

图5-3 从管理控制台管理租户

这是一个非常直观的界面,本质上是从租户管理服务中获取租户列表并显示在屏幕上。该列表当然来自您的租户管理服务,该服务会从您的服务中检索所有存储的租户并在此页面上列出。对于每个租户,您将看到其标识符、名称、状态以及您认为值得在此视图中包含的其他属性。

至少,此视图可用于查询和解决租户的状态。它还常用于在搜索日志或进行其他可能依赖租户信息的故障排除时定位唯一标识符。

除了显示租户的相关信息外,控制台还是您编辑和管理特定租户策略的地方。在这里配置的最常见功能之一是租户的层级或状态。在该示例中,您可以通过点击租户标识符链接查看更多配置详细信息。图5-4展示了特定租户的详细视图示例。

图5-4 通过控制台管理租户详细信息

这只是一个示例,但它突出了您可能附加到租户管理视图的其他选项。在此处,您可以看到与租户相关的下一级详细信息,包括子域、入驻状态等。您可以想象,根据多租户环境中存在的其他租户配置选项,此屏幕将显示更多详细信息。

这里有两个关键点需要作为概念占位符注意。首先,在图5-4的顶部,您会看到额外的详细信息,这些信息提供了关于单个租户状态的更多数据。然后,在图像的底部,您会看到一个包含超链接的区域,这些链接可带您跳转到与当前租户关联的关键基础设施资源。这些链接会直接带您到每个资源的行政管理或云提供商基础设施页面,使您能够快速访问特定租户的上下文中快速访问资源。这可以简化您的操作体验,使您能够快速导航(带有租户上下文)到任何特定租户的基础设施资源。

需要特别注意的是,您可能选择包含或不包含这些链接。这些链接在运行全栈孤岛环境时尤为有用。然而,您的环境越是资源池化,提供此类租户上下文访问权限以获取基础设施资源的价值就越低。

最后,您还会注意到图5-4右上角有一个“操作”下拉按钮。这是您对租户执行特定操作的位置。至少,您的系统应包含更新租户活动状态的功能。要执行此操作,操作员需访问管理控制台并临时停用租户。此处可能还包含其他选项,例如退役租户或在不同层级之间迁移租户(这些选项将在后续章节中详细探讨)。

本示例主要聚焦于通过控制台管理租户。然而,此处启用的所有功能通常是通过租户管理服务API执行的操作实现的。实际上,您可以设计一种体验,让这些操作和洞察直接通过API完成。具体实现方式将根据您需要支持的租户管理体验类型而异。您可以选择通过控制台完成所有操作、通过API完成所有操作,或两者结合。

在第4章关于租户入驻的讨论中,我提到了触发租户入驻的不同模型。我特别强调,新租户的入驻操作可以由租户作为自助服务体验的一部分执行,也可以通过团队开发的内部入驻工具完成。实际上,内部机制可以作为管理控制台的一部分进行展示。

自助式入驻流程相当简单。您进入注册页面,填写相关信息并提交请求。然而,问题在于,您应该在哪里展示内部管理的入驻体验?对此没有标准答案。您可能拥有自己的命令行界面(CLI)或其他工具来管理租户的入驻流程。不过,一种常见的做法是通过租户管理控制台来管理入驻流程。

你可以通过在控制台中添加一个“注册租户”操作来实现这一点。触发该操作后,将打开一个表单,你可以在其中填写所有用于注册新租户所需的信息。图5-5展示了该表单可能的样例。

图5-5 内部租户接入

这是一个基本的表单,仅用于收集和提交数据。每个多租户注册流程都可能包含租户实体名称、租户管理员用户的电子邮件地址以及他们所选择的计划或层级。此后,其余内容将取决于配置选项和多租户环境的具体性质。例如,您可能需要在此处收集子域名。或者,您可能有一个更复杂的流程,允许为租户引入完整的自定义域名。此时的关键是强调租户管理体验可能为通过管理控制台展示内部流程提供良好的入口。

租户生命周期管理

到目前为止,租户管理的重点主要在于租户管理流程的前端部分,即租户的注册和配置。现在,我希望转变视角,探讨租户管理在初始阶段之后所扮演的角色。重点将转向考虑租户在系统中运行期间可能经历的各种状态。

团队常常忽视对租户生命周期的整体管理。他们仅关注如何引入或配置租户,并将此视为租户管理服务的核心职责。确实,对于部分租户而言,创建一次即可完成其生命周期。然而,系统中也存在需要经历比单纯修改租户数据库中某个属性值更为复杂状态变更的租户。

在构建多租户环境时,您必须考虑租户在系统中可能经历的所有阶段。这些状态变化将如何传达给您?是响应外部事件,还是直接由租户管理服务驱动?与这些状态变化相关的策略是什么?在构建SaaS解决方案的租户管理组件时,这些都是您需要自问的问题。

虽然租户生命周期可能包含多种阶段,但在构建任何多租户SaaS环境时,有几个常见状态值得特别关注。以下各节将列举这些生命周期变更。

租户的激活与停用

您首先需要关注的状态是激活/停用。通常,您的SaaS环境应具备启用和禁用租户的能力。此设置主要用于管理租户访问系统的权限。在此场景下,我们并非将租户从系统中移除。我们只是切换一个开关来开启或关闭其访问权限。当租户被停用时,您的租户管理服务需要负责确定需要协调哪些操作以确保租户无法访问系统。这可能简单到调用用户管理服务来禁用该租户所有用户的身份验证,也可能更为复杂。

管理租户的活跃状态也可能与应用程序的计费体验相关。在某些情况下,计费系统可能是管理租户活跃状态的前线系统。假设一个租户停止付款。在此情况下,此信息可能首先在计费系统中被识别为逾期租户。当计费系统触发此事件时,您需要确定系统如何响应这些事件。您可能有政策在宽限期内发送消息,允许租户在账单问题解决期间继续使用系统。然而,在某个时间点,您可能确定需要停用该租户。在这种情况下,如果账单系统触发此事件,您需要一种方式将此信息传递给您的租户管理服务。

图5-6展示了计费系统可能与SaaS环境控制平面中其他服务连接的方式。

图5-6 由计费服务触发的停用

在此示例中,我引入了各种可用于根据计费提供商触发的事件来停用租户的服务。此外,我还使用了一个第三方计费系统来管理租户的计费状态。在此场景中,假设客户成功经理或计费提供商内的自动化策略已禁用了一个租户。现在,您控制平面中的计费服务需要某种方式来获取并响应此事件。具体实现方式将主要取决于计费提供商的API特性和集成模型。理想情况下,计费提供商会在租户被停用时生成一个事件。如果没有,您的计费服务可能需要一个定期检查这些状态变化的流程。在此场景中,我假设计费提供商正在向我的计费服务发送一条消息(步骤1)。

一旦计费系统检测到此事件,它将调用您的租户管理服务,发送一个“停用租户”请求(步骤2)。该服务将更新租户的状态为“非活动”,并向系统中可能受此状态变化影响的任何部分传达此新状态更改。在此图中,我假设停用是通过阻止租户进行身份验证来实现的。这通过调用控制平面中的用户管理服务实现,该服务将更新与租户关联的所有用户的活跃状态(步骤3)。理想情况下,如果您的身份提供商支持租户的组结构,您可以将此更改应用于组级别。这无疑比逐个切换用户状态简单得多。

作为停用的一部分,您还需确定此操作对当前登录系统用户的状态有何影响。您是允许他们继续使用,还是立即终止其活跃会话?许多SaaS提供商倾向于采用更被动的模型,允许租户用户完成任何活跃会话。

当然,任何可以停用的功能也应可重新启用,因此您还需考虑这一路径。这通常只需逆转之前对禁用租户所做的操作。在我们的示例中,这只需将租户状态更新为“活跃”并重新启用租户的身份验证。

在某些情况下,停用操作可能由您自己的服务发起(而非通过计费系统)。这意味着您的管理控制台将提供一个特定操作,用于触发租户停用。在此情况下,您的租户管理服务将发起停用事件,并更新受此停用事件影响的任何下游服务。

关键要点是,租户状态必须由您的租户管理服务集中管理。它应被视为管理租户状态的单一数据源,确保状态变更的影响与系统中相关部分同步。

租户的退役

现在让我们看看什么是租户的退役。您可能在想,停用和退役之间的界限在哪里。停用仅用于暂停租户的账户。它不会影响租户环境的现有资源占用。本质上,它只是禁用访问权限,允许租户在未来某个时间点重新激活。

退役通常在停用之后进行。假设一个租户决定不续订其订阅。当他们到达订阅期的最后一天时,您的系统可能会选择停用该租户,并将其保持在停用状态一段时间。这种策略允许租户返回、重新激活并继续使用其系统,且不会产生任何影响。这就像他们从未离开系统一样。这无疑能提升客户体验。然而,经过一段时间后,该租户未使用的资源可能开始产生成本和复杂性,而这些成本和复杂性并未为业务带来任何价值。此时,您需要考虑如何从停用状态过渡到退役租户的资源。

选择系统退役策略并无万能方案。所选策略将受多种因素影响。停用租户为系统带来的额外开销有多少?租户停用的频率如何?这些停用租户对管理和运营复杂性有何影响?您需要考虑多种因素来确定如何、何时以及是否选择退役租户。

现在,假设你已经到了需要对租户进行退役处理的阶段。在选择退役策略时,你有几种不同的选项。你可以选择直接删除与租户关联的所有资源,从而彻底将其从系统中移除;或者你可以选择在退役租户资源之前先对其状态进行归档。作为此过程,您需要重新考虑“恢复已退役租户”的含义。例如,您可以保留租户中对系统影响较小的元素(如租户本身、其用户等)。这可能使租户的恢复过程更加简单,同时不会为环境增加太多成本或复杂性。最终,这都是制定退役策略时需要权衡的因素。

图5-7展示了停用模型中可能包含的一些关键组件。

图5-7 租户资源的退役

在此示例中,我展示了一个场景:系统管理员启动退役流程,向租户管理服务发送退役请求(步骤1)。此时,您可以在租户管理服务的范围内实现退役功能。然而,我将退役作为一个完全独立的服务,负责协调从系统中移除租户所需的所有步骤。该服务随后被租户管理服务调用以启动退役流程(步骤3)。

在我看来,将此功能独立出来,让退役作为一个独立的流程存在,并在租户管理服务之外进行部署、管理和执行,会更加自然。退役服务负责遍历所有不同租户构造并逐一移除。这将通过基础设施自动化工具、脚本以及API调用相结合的方式实现。每个租户资源的特性可能需要采用不同的退役策略。

虽然每个SaaS解决方案都会有其独特的租户资源组合,但我仍在图中列举了几个示例,以突出可能被退役服务触及的资源类型。当然,如果系统中存在孤岛式租户基础设施,这些孤岛资源将被从系统中移除。这可能涉及移除整个孤岛部署的全部组件,或仅移除以孤岛模式部署的个别资源。租户配置和租户用户也作为示例资源列出,这些资源将在该过程中被触及。

租户数据无疑是拆卸租户时最具挑战性的领域之一。想象一下系统中可能存在共享存储的各个位置。当存在共享数据时,这意味着拆卸过程需要能够定位并有选择性地移除与其他租户数据并存的数据。图5-8展示了此退役挑战的本质概念视图。

图5-8 租户数据的退役

我提供了一个与我们的产品服务相关的数据示例。在此表中,我有一个TenantId列,其中包含将每个产品与租户关联的GUID。现在,假设我们需要退役ID为efaf7680-21cf-4f39-a1e8-3481ff0495ef的租户。退役流程必须定位并删除该表中与该租户关联的所有项。

表面上看,这似乎并不复杂。然而,请考虑该表是系统中多个表之一,且可能采用数据池化模型存储数据。系统中的每个微服务都可能管理池化租户数据,且这些服务可能依赖不同的存储技术。这意味着退役流程可能需要针对每个数据源编写独立的代码来删除数据。

在某些情况下,退役过程可能比初始化过程更为复杂。识别并优雅地移除这些租户资源的细节可能非常繁琐。自动化此过程具有挑战性,需要团队高度警惕,确保退役策略不会影响现有租户。这包括确保退役过程的负载不会造成现有租户的瓶颈或性能问题。一般来说,如果能将此过程作为一个具有非常保守资源消耗的异步过程运行,将更能限制租户影响。这与传统的批处理思维模式一致,即尽量在非高峰时段运行此类过程以减少影响。对于部分SaaS提供商,此方法可行;但其他提供商可能不具备此条件。

退役的最后一个环节聚焦于归档租户状态和数据。对于部分SaaS提供商,这可使其在不保留租户环境其他动态组件的情况下,继续保留现有租户状态。这在拥有高价值租户或对数据有重大投资的租户场景下尤为重要。

尽管归档已退役租户状态和数据的概念并不复杂,但多租户架构模型的多样性使得难以预先规定解决此问题的单一方法。不存在标准的“快照”租户环境模型——尤其是当您依赖共享资源时。相反,这通常涉及构建自有工具和策略以应对租户环境的复杂性。

最终,是否以及如何退役数据将取决于SaaS服务的性质。这通常涉及权衡业务价值、成本和复杂性之间的trade-offs。对于部分企业而言,能够以极低摩擦重新激活数据的价值可能对重新获取关键客户至关重要。而对于其他企业,数据特性及客户行为模式可能表明,投入资源构建此类能力并无足够回报。

更改租户层级

我们租户生命周期管理故事的最后一部分,探讨了将租户从一个层级迁移到另一个层级意味着什么。对于许多人来说,这一变化代表了管理租户状态最具挑战性的维度之一。

对于简单用例,从一个层级迁移到另一个层级可能并不复杂。让我们考虑一个场景:您拥有基础层和高级层的租户,这两个层级的主要区别在于吞吐量和功能。本质上,高级层租户拥有更高的整体吞吐量,并根据其从基础层迁移的状态获得额外功能的访问权限。图5-9展示了这些概念在多租户架构中的实现方式。

图5-9 全栈池模型中的层级切换

在此示例中,基本层与高级层之间的切换仅限于多租户环境中少数几个高度隔离的区域。在此,我们通过应用程序中的功能开关(featureflags)来启用高级层租户可访问的路径、功能和工作流。此外,作为API网关配置的一部分,基于层级的流量控制策略将直接应用高级层租户的流量控制策略到请求(而非基础层策略)。这将防止租户因基础层更严格的约束而被限流,并通常确保该租户获得更优的SLA。

您可以清楚地看到,在不同层级之间切换是一个相当直观的模型。由于所有租户资源均运行在池化模型中,系统只需更新租户配置以反映新的层级。随后,系统将直接使用现有的功能开关和限流策略,将新层级应用于租户的体验。这就是池化体验的优势所在——您可以以极低的复杂度和开销实现此类变更。

现在,让我们考虑在具有更复杂部署环境中跨层迁移的含义。图5-10展示了在第3章中提到的全栈池和全栈隔离部署模型之间迁移的含义。

图5-10 从全栈池迁移到全栈孤岛

在此示例中,租户2正从基础层迁移,该层采用全栈池部署模型,与其他租户共享所有资源。当该租户迁移至高级层时,实际上是切换至右侧的全栈孤岛部署模型。此次迁移首先为租户2预配置一套完整的全栈资源,并配置必要的路由以将流量导向该孤岛。如果仔细思考,此次迁移的部分过程将与任何高级层租户的入驻体验高度相似。事实上,利用部分入驻代码来简化此次迁移并非不可行。

当需要将租户的现有状态迁移到全栈孤岛环境时,情况会变得稍微复杂一些。此时,您必须考虑这是否是一次零停机迁移,还是需要租户停用后才能迁移到新层。你还需要编写新代码,将所有数据和状态从共享环境迁移到新的全栈隔离环境。这就是迁移工作变得繁重的地方。从许多方面来看,你正在面对任何环境迁移中常见的经典挑战。迁移任何软件环境时常用的许多原则和策略在这里同样适用——只是迁移范围扩展到了租户级别。

尽管迁移到全栈孤岛模型涉及众多复杂环节,但迁移逻辑和路径相对清晰。数据迁移是。现在,让我们再增加一个复杂因素。让我们看看在使用混合部署模型的环境中,更改层级意味着什么,其中每个微服务可能根据租户的层级具有更细粒度的孤岛和池实现。

考虑在类似图5-11所示的模型中,从基本层迁移到高级层可能意味着什么。

图5-11 混合模式层级迁移

我特意将这部分设计得稍显复杂,以便突出在混合部署环境中迁移时会遇到的某些复杂性。如果你观察这些微服务,会发现它们与层级的映射关系更加细粒度。在左侧,您可以看到为基础层租户提供的服务。这里有一个有趣的细节:订单微服务在所有层级中都是隔离的。中间部分,履行服务为基础层和高级层提供共享计算资源。然而,它为基础层提供共享存储,而高级层则使用隔离存储。最后,高级层租户在产品微服务中获得完全隔离的计算和存储资源。

这与我们在探讨混合模式部署模型基础时看到的模式非常相似。不过,现在我们需要考虑租户从基础层迁移到高级层的影响。假设租户3(T3)正在迁移到高级层。这里的步骤不太明显。您必须考虑每个服务如何应用分层模型,并确定迁移所需的新资源。要实现此次迁移,订单微服务无需进行任何更改。对于履行服务,您需要将存储从共享模型迁移到隔离存储模型。最后,对于产品微服务,您需要为租户3provision新的计算和存储资源,并将数据从共享数据库迁移到新的隔离产品存储空间。

与迁移到全栈隔离部署时面临的许多挑战类似,这些挑战在混合模式部署环境中依然存在。数据迁移仍然是一个挑战。然而,您将面临一个更复杂的变更网络,这些变更受您将分层映射到系统各层的方式影响。

环境中分层映射的方式。好消息是,与全栈隔离部署迁移类似,此次迁移也可借助部分与您的入驻体验相关的工具和机制。迁移相关的复杂性往往与入驻体验的细节相互交织。

对于您考虑的任何级别的迁移方案,都必须考虑此迁移对当前使用您系统的租户可能产生的影响。您需要确保租户数据和状态的提取不会对现有工作负载造成任何不利影响。如果此迁移对您的环境造成任何干扰,都可能破坏环境的整体稳定性和可用性。

虽然这里的所有关注点都放在迁移到更高级别的层级上,但您的环境还必须支持租户降级到较低级别层级的模型。在此模式下,我们本质上是在实现与升级层级相反的操作。这可能只是更新配置以反映新的层级,也可能涉及将基础设施和数据迁移到新层级。

如果您从高级层迁移到基础层,且此次迁移涉及系统部分从孤立基础设施迁移到共享基础设施,则此次迁移将关注如何将计算资源和数据迁移到共享资源池中。

租户管理 | 构建多租户SaaS系统 | IT书单