应用部署是一个将软件提供给用户的过程,通常包含配置环境、安装及测试等步骤。现如今,大部分企业在部署新的应用程序时,会至少自动化其中一些步骤。应用程序部署的策略会影响该应用的性能、稳定性以及运行速度,因此有时会在向所有人提供更新之前,先对一小部分用户进行测试。
 

软件开发和用户体验的现代标准要求开发人员持续地更新他们的项目。部署和集成已经成为日常操作——一个现代的应用程序每天都需要部署。这就是为什么现在拥有一个有效的部署技术比以往任何时候都更重要。
 

当下,企业追求更为灵活和可扩展的系统,因此微服务架构、云基础设施变得随处可见。灵活的架构意味着诸多开发团队会牵涉其中,这会给部署带来挑战。
 

本文将介绍应用部署过程的几个主要阶段以及不同的应用部署模式。
 

应用部署的主要阶段

前期准备/计划阶段

在计划准备阶段,以下步骤十分重要:

  • 确认协作方: 软件开发的过程中会涉及到不同的团队。部署前应该告知所有协作方,以尽量减少开发、运维和安全团队之间的摩擦。
  • 列出第三方工具: 确定部署流程中所需要的所有工具以及要求,这可以帮助你确保所有协作方都知道如何有效地使用它们并且最大限度地减少问题的产生。
  • 设置测试环境: 在正式发布新产品前,一定要测试软件
  • 设计清晰的部署步骤: 与团队密切沟通以确保部署流程清晰明了
  • 创建回滚计划: 如果新版本出现严重的问题可以启用这一计划。渐进式交付策略让无缝自动回滚部署成为可能。
  • 设置性能监控指标: 常用的指标有内存、CPU使用率以及查询响应时间。你可以使用这些基本指标和自定义KPI来衡量部署的有效性。在渐进式交付中,你甚至可以使用这些指标来自动确定部署是否成功。
     

测试阶段

测试阶段可以在部署之前验证软件是否可靠。在这一阶段中,需要考虑以下方面:

  • 编写单元测试: 其目的是测试软件的其中某个部分,以验证其独立于其他部分的行为是否可以正常运行。当结果与需求一致时,单元测试通过,否则失败。
  • 在CI流程中集成测试: 将单元测试集成到共享代码仓库中以自动化构建和验证每个部分。在部署之前完成这个步骤可以更轻松地修复和移除bug。
  • 在staging环境中部署测试: 模拟生产环境,并使用它来测试更新、代码及其他方面,以确保软件按预期运行。
  • 运行端到端的测试: 从头到尾测试应用程序的工作流程,过一遍它可以执行的操作,检查它是否可以与其他组件(如网络连接、硬件等)一起正常运行。
  • 验收测试: 这是测试流程的最后一步,需要与相关方或真实用户一起验证软件。他们的反馈可以帮助决定软件是否生产就绪。
  • 冒烟测试: 创建一个专门的测试套件,在部署之后在生产中运行,以验证刚刚发布的软件没有缺陷。
     

部署及发布阶段

应用部署的最终阶段,包括以下方面:

  • 部署到生产环境: 将更新推送到生产环境中,用户可以使用它们。
  • 监控产品性能: 根据KPI来监测产品的性能,检查HTTP errors和数据库性能等。
  • 监控环境健康: 借助监控工具来识别软件环境相关的潜在问题,比如操作系统、数据库系统以及编译器等。
  • 执行自动化回滚: 借助冒烟测试和指标来衡量发布是否成功并且当存在问题时自动回滚到上一个版本。
  • 跟踪日志: 借助日志获得软件运行的可见性,比如了解软件如何运行在基础设施上,如何调查错误并识别潜在的安全风险。
  • 记录发布的版本和注释: 保存对产品进行修改时创建的新版本的副本,这有助于保持一致性。

应用部署模式

金丝雀发布

金丝雀发布可以逐一发布新特性,而非完整的更新版本。开发人员让旧版本处于活跃状态,并比较更新前后的实例性能。此外,金丝雀发布会先将新功能提供给一小部分用户使用,根据小范围的用户反馈对产品进行必要的调整。
 

以下是金丝雀发布的基本步骤:

  • 开发人员上传新版本(假设其为Version B)到服务器。
  • 主要用户群体依旧定向到 Version A,与此同时,小部分用户开始使用 Version B,进而开发人员可以监控新版本的性能并进行改进。
  • 对 Version B 进行必要的调整之后,开发人员就会将大部分流量定向到更新完毕的实例中。此时团队开始测量性能并将其与旧版本进行对比。
  • 当 Version B 已经足够稳定,开发人员就会切断 Version A 并将流量完全重定向到更新后的代码库中。
     

要保证金丝雀发布的成功,开发人员必须设置清晰的性能指标,原始版本和金丝雀版本(更新版本)应该同时在相同的条件下部署,以更客观地进行分析。
 

金丝雀发布的优势之一是可以最大限度地减少宕机时间并且避免新版本中存在潜在的问题。 此外,通过在小部分用户中测试特性,开发人员可以在对更多用户产生影响之前发现并修复问题,这有助于确保新功能或更新不会对用户体验产生负面影响。
 

这种部署模式也存在缺陷——十分耗时。金丝雀的测试和部署是分几个阶段进行的,需要时间进行彻底的监控和评估。正因为如此,不是所有用户都能马上从新的功能和升级中受益。
 

正如许多同时运行两个版本的部署策略一样,开发人员需要牢记并确保技术栈和数据库的兼容性。
 

蓝/绿部署

蓝/绿部署是指同时部署两个应用版本,当前版本(蓝)和新版本(绿)在不同的环境中运行,并且只有一个版本是实时运行的。当绿版本进行测试时,蓝版本继续运行,反之亦然。两个版本都可以处于活跃状态,但只有一个是公开的(通常是蓝版本)。
 

当测试完成、新部署就绪,就可以安全地切换流量到绿版本。此后,蓝环境可以保留下来以执行回滚操作或在未来的更新中使用此前的功能。
 

蓝/绿部署几乎消除了宕机时间并允许即时回滚。 蓝/绿环境的隔离可以保护实时部署在测试阶段免受 bug 的影响。虽然这种部署策略的风险较低,但实施成本较高,因为必须覆盖两个环境进行操作,会增加存储空间、计算能力及硬件等成本。为了在蓝绿环境之间无缝切换,开发团队还需要保证数据格式和存储的兼容性。
 

滚动部署

使用滚动部署,开发人员可以同时上传几个版本——活跃的版本数量被称为窗口大小(window size)。开发者可以1次只上传1个实例(即窗口大小设置为1)或在集群中同步更新部署应用程序。为了更快且更安全地部署,开发人员常常使用容器技术。容器应用部署包括 Docker 和 Kubernetes,它们是隔离更新版本、启用和禁用服务以及跟踪变化的常用工具。
 

滚动部署提供了灵活性,并减少了停机时间,因为它只在新版本准备好之后再将流量重定向到新版本。 同时,它也降低了部署风险,因为更新存在的缺陷只影响到有限的用户。但是这一部署方法回滚速度较慢,因为它需要一个渐进的方法。
 

另外,新的部署必须向下兼容,因为它们需要与旧版本共存。如果应用程序需要会话持续存在,那么确保负载均衡支持粘性会话也十分重要。
 

影子(Shadow)部署

影子部署包含两个活跃的平行版本,将传入请求 fork 到当前版本,然后将它们发送到新版本。这种方法有助于测试新功能如何在不影响流量的情况下处理生产负载。当新版本满足性能和稳定性要求后,即可安全上线应用。
 

虽然这种模式十分专业,设置起来也复杂,但它消除了对生产的影响,利用流量复制来测试使用影子数据的bug。测试结果是高度准确的,因为它们使用生产负载来创建模拟现实条件。影子部署被认为是一种低风险的方法,并经常与其他方法相结合,比如金丝雀部署。
 

执行影子部署的步骤:

  • 应用层级的实现: 开发人员编写的函数既可以向应用程序的当前版本也可以向新版本发送输入。输入和输出可以同时处理,也可以在一个队列中异步处理,以获得更高的精度。团队可以选择在客户端划分输入,在浏览器或移动设备中设置不同的API目标。
  • 基础设施层级的实现: 开发人员配置负载均衡以 fork 格式以及支持两个版本的端点。开发人员需要确保没有重复,应用程序绝不能两次请求相同的数据。新版本应该从第一版本中接收用户的信息,否则,用户将不得不重复输入支付或注册数据。
  • 影子模式结果评估: 团队需要注意数据的错误,比较两个版本的性能,检查新版本能否正确接收旧版本的输入。