应用部署和测试策略


本文档简要介绍了常用的应用部署和测试模式。我们将介绍这些模式的工作原理、其具备的优势以及实现这些模式时需要考虑的事项。

假设你要将正在运行的应用升级到新版本。为确保顺利发布,你通常需要考虑以下事项:

  • 如何最大限度地减少应用停机时间(如果存在)。
  • 如何以对用户影响最低的方式管理和解决突发事件。
  • 如何以可靠、高效的方式处理失败的部署。
  • 如何最大限度地减少人数和处理错误,以实现可预测且可重复的部署。

你选择的部署模式主要取决于你的业务目标。例如,你可能需要在完全没有停机时间的情况下发布更改,或者在正式发布某项功能之前先对一个环境或一部分用户发布更改。本文档中介绍的每种方法都说明了在部署被视为成功之前需要实现的特定目标。

本文档适用于负责为各种应用、系统和框架定义和实施发布及部署策略的系统管理员和 DevOps 工程师。

部署某项服务后,系统不一定会立即向用户显示该服务。 有时,只有在服务发布之后,用户才会在应用中看到更改。但是,当服务时,部署和发布会同时进行。在这种情况下,当你部署新版本时,它会开始接受生产流量。此外,还有一些部署策略可同时预配多个服务版本。这些部署模式可让你控制和管理接收传入请求的版本。

本部分介绍的部署模式可让你灵活地自动发布新软件。你可以根据你的目标选择最适合你的方法。

通过重新创建部署,你可以在为新应用版本扩容之前完全缩减现有应用版本。

下图演示了为应用重新创建部署的工作原理。

recreate-deploy

图 1. 重新创建模式

版本 1 代表当前应用版本,版本 2 代表新应用版本。更新当前应用版本时,你首先将版本 1 的现有副本缩减为零,然后为新版本并发部署副本。

重新创建方法的优势在于操作简单。你无需同时管理多个应用版本,因此可以避免数据和应用向后兼容性的问题。

在更新过程中,重新创建方法会导致出现停机时间。对于可以处理维护期或服务中断的应用,停机时间不是问题。 但是,如果你的关键任务应用具有高服务等级协议 (SLA) 和可用性要求,则你可以选择其他部署策略。

在滚动更新部署中,你会更新一部分正在运行的应用实例,而不是同时更新每个应用实例,如下图所示。

rolling-update-deploy

图 2. 滚动更新模式

在此部署方法中,你同时更新的实例数称为窗口大小。在上图中,滚动更新的窗口大小为 1。一次更新一个应用实例。如果你有一个大型集群,则可能需要增加窗口大小。

通过滚动更新,你可以灵活地更新应用:

  • 你可以在缩减旧版本之前为新版本应用实例扩容(这个过程称为 “超额配置升级”)。

  • 你可以指定在并发为新实例扩容时不可用的最大应用实例数。

  • 没有停机时间。根据窗口大小,你可以逐步更新部署目标,例如每次更新一个或每次更新两个。只有在新版本应用准备好接受流量之后,你才将流量定向到更新后的部署目标。

  • 降低了部署风险。当你逐步发布更新时,新版本中的任何不稳定因素都只会影响一部分用户。

  • 回滚速度较慢。如果新发布的版本不稳定,你可以终止新副本并重新部署旧版本。但是,与发布一样,回滚是一个需要逐步完成的过程。

  • 向后兼容性。由于新代码和旧代码同时存在,用户可能会被随机路由到其中一个版本。 因此,请确保新部署具有向后兼容性;也就是说,新应用版本可以读取和处理旧版本存储的数据。这些数据可能包括存储在磁盘上、数据库中或作为用户浏览器会话的一部分的数据。

  • 粘性会话。如果应用需要会话持久性,我们建议负载均衡器支持粘性和连接排空 [1] 。 此外,我们建议你尽可能调用会话共享(通过会话复制或使用数据存储区的会话管理),以便分离会话与底层资源。

在蓝绿部署(也称为红黑部署)中,你将执行两个相同的应用部署,如下图所示。

bluegreen-deployment-pattern

图 3. 蓝绿部署模式

在该图中,蓝色代表当前应用版本,绿色代表新的应用版本。一次只能存在一个版本。 在创建和测试绿色部署时,流量将路由到蓝色部署。测试完成后,你可以将流量路由到新版本。

部署成功后,你可以保留蓝色部署以进行可能的回滚,也可以停用该部署。或者,你可以在这些实例上部署更高版本的应用。在这种情况下,当前(蓝色)环境将作为下一个版本的暂存区域。

  • 零停机时间。蓝绿部署允许快速切换,没有停机时间。

  • 即时回滚。你可以在部署过程中随时回滚,只需调整负载平衡器即可将流量定向回蓝色环境。 停机时间的影响取决于你在检测到问题后将流量切换到蓝色环境所需的时间。

  • 环境分离。蓝绿部署可确保启动并行绿色环境不会影响支持蓝色环境的资源。这种分离降低了部署风险。

  • 费用和运营开销。采用蓝绿部署模式可能会增加运营开销和费用,因为你必须维护具有相同基础架构的重复环境。

  • 向后兼容性。蓝色和绿色的部署可以共享数据点和数据存储区。我们建议你验证应用的两个版本是否都可以使用数据存储区的架构和记录的格式。如果你需要回滚,需要在两个版本之间无缝切换,则必须具备向后兼容性。

  • 切换。如果你打算停用当前版本,我们建议你允许对现有事务和会话进行适当的连接排空。此步骤允许顺利完成或终止当前部署处理的请求。

本部分介绍的测试模式通常用于在合理的并发和负载水平下验证服务在合理期限内的可靠性和稳定性。

在 Canary 版测试中,你将部分发布更改,然后根据基准部署评估其性能,如下图所示。

canary-test-pattern

图 4. 金丝雀测试模式

在此测试模式中,你将一同部署应用的新版本和生产环境版本。然后,你可以将一定比例的流量从生产环境版本分离并路由到 Canary 版本,并评估 Canary 版的性能。

你可以在配置 Canary 版时选择用于评估的关键指标。我们建议你将 Canary 版与等效基准(而非实际生产环境)进行比较。

为减少可能影响分析的因素(例如缓存、长期有效的连接和哈希对象),我们建议你对应用的基准版本执行以下步骤:

  • 确保应用的基准版本和生产环境版本相同。

  • 在部署 Canary 版的同时部署基准版本。

  • 确保基准部署(例如应用实例数和自动扩缩政策)与 Canary 部署匹配。

  • 使用基准版本处理与 Canary 版相同的流量。

在 Canary 版测试中,部分发布可以遵循各种分区策略。 例如,如果应用具有按地理位置分布的用户,你可以先将新版本发布到一个地区或一个特定位置。

  • 能够测试实时生产流量。你可以对实时生产流量运行 Canary 版测试,而不是在暂存环境中使用模拟流量来测试应用。 采用 Canary 版发布时,你需要确定发布新应用的增量,以及何时触发版本中的下一步。Canary 版需要足够的流量,以便监控可以明确检测到任何问题。

  • 快速回滚。你可以将用户流量重定向到旧版本应用来快速回滚。

  • 零停机时间。Canary 版本可让你将实时生产流量路由到应用的不同版本,没有停机时间。

  • 发布速度较慢。每个增量版本都需要在合理的时间段内进行监控,因此可能会导致整个版本延迟。Canary 版测试通常需要几个小时的时间。

  • 可观测性。实现 Canary 版测试的前提条件是能够有效观测和监控你的基础架构和应用堆栈。实现强大的监控功能可能需要投入大量精力。

  • 向后兼容性和粘性会话。与滚动更新一样,Canary 版测试可能会带来向后兼容性和会话持久性方面的风险,因为在部署 Canary 版时,环境中运行了多个应用版本。

通过 A/B 测试,你可以使用变体实现来测试假设。 A/B 测试可用于根据数据做出业务决策(而不仅仅是预测)。

执行 A/B 测试时,你将根据路由规则将一部分用户路由到新功能,如下图所示。

ab-test-pattern

图 5. A/B 测试模式

路由规则通常包括浏览器版本、用户代理、地理定位和操作系统等因素。衡量并比较版本后,应使用能够产生更好结果的版本更新生产环境。

A/B 测试最适合用于衡量应用中功能的有效性。前面介绍的部署模式的用例侧重于安全发布新软件并以可预测的方式回滚。在 A/B 测试中,你可以控制新功能的目标受众群体,并监控用户行为方面的统计显著性差异。

  • 设置复杂。A/B 测试需要一个代表性样本,该样本可用于提供一个版本优于另一个版本的证据。 你需要预计算样本大小(例如,使用 A/B 测试样本大小计算器),并在合理的时间段内运行测试,以使统计显著性达到至少 95%。

  • 结果的有效性。有一些因素会导致测试结果出现偏差,包括假正例、采样偏差或外部因素(如季节性促销或营销推广)。

  • 可观测性。当你对重叠的流量运行多个 A/B 测试时,监控和问题排查流程可能会比较困难。 例如,如果你测试的是产品页面 A 和产品页面 B,或者是结算页面 C 和结算页面 D,那么分布式跟踪对于确定指标(例如不同版本之间的流量拆分等)非常重要。

诸如 Canary 版测试之类的顺序实验方法可能会在测试的早期阶段向客户提供较低的应用版本。你可以使用模拟之类的脱机方法来管理此风险。 但由于新版本没有用户交互,因此脱机方法无法验证应用的改进。

使用影子测试时,你可以一同部署和运行新版本和当前版本,但对用户隐藏新版本,如下图所示。

shadow-test-pattern

图 6. 影子测试模式

传入的请求会在测试环境中产生镜像并重放。此过程可以实时发生,也可以在对新部署的服务重放之前捕获的生产流量副本之后异步发生。

你需要确保影子测试不会触发可能改变现有生产环境或用户状态的负面效果。

  • 对生产环境没有影响。由于流量是复制的,因此处理影子数据的服务中的任何 bug 都不会影响生产环境。

  • 使用生产负载测试新的后端功能。结合使用 Diffy 等工具时,生成影子流量可让你针对实时生产流量衡量服务的行为。 此功能可让你测试应用版本之间的错误、异常、性能和结果是否对等。

  • 降低了部署风险。影子流量通常与 Canary 版测试等其他方法结合使用。在使用影子流量测试新功能后,你可以将功能逐步发布给更多用户来测试用户体验。 除非应用满足稳定性和性能要求,否则不会全面发布。

  • 负面效果。使用影子流量时,你需要谨慎处理能够更改状态或与第三方服务交互的服务。例如,如果你想对购物车平台的付款服务进行影子测试,客户可以为其订单支付两次。为避免影子测试导致意外更改或进行其他容易产生风险的交互,我们建议你使用存根或虚拟化工具(如 Hoverfly)代替第三方系统或数据存储区。
  • 费用和运营开销。影子测试的设置相当复杂。此外,与蓝绿部署一样,影子部署会产生费用和操作方面的影响,因为设置需要并行运行和管理两个环境。

你可以通过多种方式部署和发布应用。每种方法都有其优点和缺点。最佳选择取决于你的业务需求和限制。请考虑以下因素:

  • 对你而言哪些事项最为重要?例如,你可以接受停机时间吗?费用方面是否存在限制?你的团队成员是否掌握执行复杂的发布和回滚设置所需的技能?

  • 你是否有严格的测试控制措施,或者是否希望针对生产流量测试新版本以确保版本的稳定性并限制任何负面影响?

  • 你是否希望对一组用户进行功能测试,以交叉验证某些业务假设?你能否控制目标用户是否接受更新?例如,移动设备上的更新需要明确的用户操作,并且可能需要额外的权限。

  • 你的环境中的微服务是否完全自治?或者,你是否混合运行微服务应用和难以更改的传统应用?

  • 新版本是否涉及架构更改?如果是,架构更改是否过于复杂,以至于无法与代码更改分离?

下表汇总了本文档前面介绍的部署和测试模式的重要特征。在权衡各种部署和测试方法的利弊时,请考虑你的业务需求和技术资源,然后选择对你最有利的选项。

部署或测试模式 零停机时间 实时生产流量测试 根据条件向用户发布 回滚时长 对硬件和云费用的影响
重新创建
版本 1 已终止,版本 2 已发布。
x x x 速度快,但会由于停机时间而中断 无需额外设置
滚动更新
版本 2 逐步推出并取代版本 1。
x x 可能需要对超额配置升级进行额外设置
蓝绿
版本 2 与版本 1 一同发布;流量在经过测试后会切换到版本 2
x x 即时 需要同时维护蓝色和绿色环境
Canary
版版本 2 面向部分用户发布,随后全面发布。
x 无需额外设置
A/B
版本 2 在特定条件下面向一部分用户发布。
无需额外设置
影子
版本 2 接收实际流量而不影响用户请求。
x 不适用 需要维护并行环境才能捕获和重放用户请求

为将部署和测试风险降到最低,应用团队可以遵循以下几种最佳做法:

  • 向后兼容性。在同时运行多个应用版本时,请确保数据库与所有有效版本兼容。例如,新版本要求对数据库进行架构更改(例如新列)。 在这种情况下,你需要更改数据库架构使其向后兼容旧版本。完成全面发布后,你可以移除对旧架构的支持,仅保留对新版本的支持。 实现向后兼容性的一种方法是分离架构更改与代码更改。 如需了解详情,请参阅并行更改数据库重构模式。

  • 持续集成/持续部署 (CI/CD)。CI 可确保签入功能分支的代码只有在成功通过依赖项检查、单元和集成测试以及构建流程后,才能与其主分支合并。 因此,对应用的每次更改都需要先进行测试,然后才能进行部署。通过 CD,CI 构建的代码工件会被打包,并准备部署到一个或多个环境中。

  • 自动化。如果你需要向用户持续交付应用更新,我们建议你构建一个自动化流程,以便可靠地构建、测试和部署软件。 建议代码更改自动流经包含工件创建、单元测试、功能测试和正式版发布的 CI/CD 流水线。 使用 Cloud Build、Cloud Deploy、Spinnaker 和 Jenkins 等自动化工具,你可以自动完成部署流程,使其更高效、可靠且可预测。

  • IaC 和 GitOps。 如果你需要管理复杂的部署和测试策略,请考虑使用基础架构即代码 (IaC) 和 GitOps 工具。 将 IaC 与 Terraform 和 Config Connector 搭配使用有助于你使用声明式语言来定义基础架构和策略。 将 GitOps 与 Config Sync 和 Argo CD 搭配使用有助于你使用 git 管理你的代码。

  • 回滚策略。有时候会出现问题。我们建议你创建回滚策略,以便在发生意外情况时遵循。拥有可靠的回滚策略可以帮助管理员和 DevOps 工程师管理风险。 你可以使用支持回滚作为内置特性的平台(例如 App Engine 和 Cloud Run)来创建回滚策略。 为支持你的回滚需求,你还可以使用发布自动化工具,例如 Cloud Deploy、Spinnaker 和 Argo RollOuts。

  • 部署后监控。如需监控关键指标并在部署或测试失败时提醒负责团队,请使用 Google Cloud 的运维套件构建监控系统。 你还可以为未通过健康检查的部署启用自动回滚。使用 Error Reporting、Cloud Trace 和 Cloud Profiler 可帮助你找到简单和复杂的部署后问题的原因。


脚注:

[1]  连接排空过程旨在确保在从实例组中移除虚拟机或从可用区网络端点组 (NEG) 中移除端点时,为进行中的现有请求留出一定的时间,让这些请求可以完成。 ↩︎ 

[1]  如需启用连接排空功能,请为后端服务设置连接排空超时时间。超时持续时间一般介于 0 到 3600 秒之间(含边界值)。 ↩︎ 

[1]  在指定的超时持续时间内,系统会为对已移除虚拟机或端点发出的现有请求留出一定的时间,让这些请求可以完成。负载均衡器不会向已移除的虚拟机发送新 TCP 连接。达到超时时长之后,与该虚拟机的所有其余 TCP 连接都会关闭。 ↩︎