推出的故事影响了一切


12f-2 的现实敌人

4月底,当白人步行者围困温特费尔时,发生了一些更有趣的事情,我们进行了一次不寻常的推广。 原则上,我们会不断在产品中推出新功能(就像其他所有人一样)。 但是这一个人并不像其他任何人一样。 它的规模如此之大,以至于我们可能犯的任何潜在错误都会影响我们所有的服务和用户。 结果,我们在计划内和宣布的停机时间内按计划推出了所有产品,而对销售没有任何影响。 这篇文章是关于我们如何实现这一目标的,以及那些希望在家里重复的人。

现在,我将不描述我们的体系结构和技术决策,而仅说明其工作原理。 这些是关于最困难的部署之一的发生方式的边际注释,我观察到了这一点,并且我直接参与了其中。 我不假装是完整的或技术性的细节,也许它们会出现在另一篇文章中。

背景+这是什么功能


我们正在构建Mail.ru云解决方案 (MCS)云平台,我将在其中担任CTO。 现在-是时候附加到我们的平台IAM(身份和访问管理),该平台提供对所有用户帐户,用户,密码,角色,服务等的统一管理。 为什么在云中需要它是一个显而易见的问题:所有用户信息都存储在其中。

通常,这种事情在任何项目的开始就开始构建。 但是MCS历来有所不同。 MCS分为两个部分:

  • 具有自己的Keystone授权模块的Openstack,
  • 基于项目Cloud Mail.ru的Hotbox(S3-storage),

然后出现了新的服务。

本质上,这是两种不同的授权类型。 另外,我们使用了一些单独的Mail.ru开发,例如常规的Mail.ru密码存储以及一个自写的openid连接器,该连接器在虚拟机的Horizo​​n面板(本机UI OpenStack)中启用了SSO(传递授权)。

执行IAM对我们来说意味着将所有这些都组合成一个完整的系统。 同时,在此过程中不要失去任何功能,为将来创造一个储备,这将使我们能够在不进行重构的情况下透明地对其进行修改,并在功能方面进行扩展。 同样在开始时,用户出现了访问服务的角色模型(中央RBAC,基于角色的访问控制)和其他一些小东西。

事实证明,这项任务非常艰巨:python和perl,多个后端,独立编写的服务,多个开发团队和管理员。 最重要的是,战斗生产系统上有成千上万的实时用户。 所有这些都必须编写,而且最重要的是,必须在没有人员伤亡的情况下进行。

我们要推出什么


如果非常不礼貌,我们会在4个月内准备以下内容:

  • 他们制作了几个新的恶魔,这些恶魔汇总了以前在基础结构的不同部分工作的功能。 其他服务被指定为这些恶魔形式的新后端。
  • 我们编写了自己的密码和密钥中央存储库,可用于所有服务,可以根据需要自由修改。
  • 他们从头开始为Keystone编写了4个新的后端(用户,项目,角色,角色分配),实际上,它替代了其基础,现在充当了我们用户密码的单一存储库。
  • 我们教导所有的Openstack服务将其策略转给第三方策略服务,而不是从每个服务器本地读取这些策略(是的,默认情况下,Openstack就是这样!)

如此大的变更需要由不同的开发团队编写的多个系统中的大型,复杂且最重要的是同步变更。 组装后,整个系统应正常工作。

如何推出此类更改而又不搞砸呢? 首先,我们决定展望未来。

推出策略


  • 可能分几个阶段推出,但这将使开发时间增加三倍。 另外,一段时间后,我们将使数据库中的数据完全不同步。 我将不得不编写自己的同步工具,并在多个数据仓库中使用很长时间。 这会带来各种各样的风险。
  • 他们可以为用户透明地准备的所有工作都是预先完成的。 花了两个月的时间。
  • 我们允许自己宕机几个小时-仅用于用户操作来创建和修改资源。
  • 对于所有已经创建的资源的工作,停机时间是不可接受的。 我们计划在推出资源时应在不造成停机的情况下正常工作,并且不会影响客户。
  • 为了减少对客户的影响,如果出现问题,我们决定在周日晚上推出。 在晚上,管理虚拟机的客户减少了。
  • 我们警告所有客户,在选择推出的这段时间内,将无法进行服务管理。

离题:什么是推广?


<警告理念>

每位IT专家都将轻松回答什么是首次展示。 您放入CI / CD,然后自动将所有内容交付给产品。 :)

当然是这样。 但是困难在于,使用用于自动化代码交付的现代工具,对滚动本身的了解已经消失了。 您如何看待现代汽车,却忘记了车轮的史诗般的发明。 一切都是如此自动化,以至于往往在推出时都没有意识到整个画面。

整个情况如下。 部署包括四个主要方面:

  1. 代码交付,包括数据修改。 例如,他们的迁移。
  2. 代码回滚-发生错误时返回的能力。 例如,通过创建备份。
  3. 每次推出/回滚操作的时间。 必须了解前两点的任何操作时间。
  4. 受影响的功能。 有必要评估预期的正面和负面影响。

为了成功部署,必须考虑所有这些方面。 通常,他们只评估第一点,最好是评估第二点,然后将其视为成功。 但是第三和第四更重要。 如果推出需要3个小时而不是一分钟,哪个用户会喜欢它? 还是如果多余的东西影响了推广? 还是一项服务的停机时间会导致不可预测的后果?

行为1..n,准备释放


起初,我想简要描述一下我们的会议:整个团队,其各个部分,关于咖啡要点的讨论,争议,测试,头脑风暴。 然后我认为那将是多余的。 这通常需要四个月的开发时间,尤其是当您编写的不是可以持续交付的内容,而是生活系统中的一项重要功能时。 这会影响所有服务,但用户除了“ Web界面中的一个按钮”外,不应更改任何其他内容。

我们对如何开展会议的理解,在每次新会议中都有很大的变化。 例如,我们将更新整个计费基础。 但是他们计算了时间,并意识到不可能在合理的推出时间内做到这一点。 我们花了将近一个星期的时间来对计费数据库进行分片和存档。 此后,当无法达到预期的推出速度时,他们订购了另一台功率更大的熨斗,将整个底座拖到了那里。 并不是说我们不想更早地做到这一点,但是当前推出的需求并没有给我们任何选择。

当我们中的一个人怀疑推出是否会影响我们的虚拟机的可用性时,我们花了一周的时间进行测试,实验,解析代码,并清楚地了解这不会在我们的产品中发生,甚至最怀疑的人也对此表示赞同。

同时,技术支持人员进行了独立的实验,向客户写了有关如何连接的说明,这些说明应该在推出后会有所改变。 他们使用了用户友好的UX,编写了说明并提供了个人建议。

我们已将所有可能的推出操作自动化。 任何操作都经过脚本编写,即使是最简单,不断进行的测试也是如此。 他们争论了如何最好地关闭服务-降低守护进程或使用防火墙阻止对服务的访问。 在推出的每个阶段都创建了一个团队清单,并不断更新。 我们绘制并针对所有推出工作不断更新甘特图,并提供时间安排。

等等...

最后一幕,推出之前


...是时候推出了。

俗话说,一件艺术品不能完成,只能完成它。 有必要做出坚定的努力,了解您将无法找到所有东西,但要相信您已针对所有可能的情况做出了所有合理的假设,关闭了所有严重的错误,并且所有参与者都已尽力而为。 您投放的代码越多,就越难以说服自己(此外,任何人都知道不可能预见一切)。

当我们确信我们已尽一切可能为用户消除与意外影响和停机有关的所有风险时,我们决定准备推出。 那就是-除了以下以外,任何事情都会出错:

  1. 用户基础架构的影响力(对我们而言是最宝贵的)
  2. 功能:推出后我们对服务的使用应与之前相同。

推出



两个正在滚动,八个不干扰

我们会在7个小时内对用户的所有请求进行停机。 目前,我们既有推出计划,也有回滚计划。

  • 部署本身大约需要3个小时。
  • 2小时-测试。
  • 2小时-保留可能的变更回滚。

已为每个动作,所需的时间,依次执行的操作,并行执行的操作编译了甘特图。


甘特卷展图的一部分,较早的版本之一(无并行执行)。 最有价值的同步工具

所有参与者都有自己的角色,要推广,做什么任务,要负责。 我们正在努力使每个阶段都自动进行,回滚,收集反馈并再次回滚。

大事记


因此,有15个人在4月28日星期日晚上10点上班。 除了主要参与者外,还有一些人只是为了支持团队,为此特别感谢他们。

另外,值得一提的是,我们的主要测试人员正在休假。 没有测试就不可能推出,我们正在研究选项。 一位同事同意对我们进行休假测试,她对此表示感谢,整个团队对此深表感谢。

00:00。 停下
我们停止用户要求,挂上铭牌,他们说,这是技术工作。 监视大喊,但一切正常。 我们确认没有任何下降,只是应该下降。 我们开始进行迁移工作。

每个人都有针对这些要点的印刷版计划,每个人都知道谁在做什么以及在什么时候做。 每次操作后,我们都会检查不超过其时间的时间,一切都按计划进行。 那些在当前阶段不直接参与推广的人,可以通过启动在线玩具(Xonotic,类型3 kwaki)进行准备,以免干扰同事。 :)

凌晨02:00 推出
令人惊喜的是-由于数据库和迁移脚本的优化,我们提前一个小时完成了发布。 普遍的呐喊“滚出!” 产品中的所有新功能,但到目前为止,我们只能看到该界面。 每个人都进入测试模式,整理成堆,然后开始查看最终发生了什么。

效果不是很好,十分钟后我们就明白了,当时没有任何联系,并且在团队成员的项目中不起作用。 快速同步,解决我们的问题,确定优先级,分成小组并进行调试。

上午2:30 两大问题与四眼
我们发现两个大问题。 我们意识到,客户将看不到某些已连接的服务,并且合作伙伴帐户会出现问题。 在某些情况下,两者都与不完善的迁移脚本相关联。 我们现在需要修复它。

我们编写查询来解决此问题,至少需要4眼。 我们在登机口上滚动以确保它们正常工作并且不会损坏任何东西。 你可以继续。 同时,我们通常的集成测试开始,它将检测更多问题。 它们都很小,但也需要修理。

上午03:00 -2个问题+2个问题
前两个大问题已解决,几乎所有小问题也已解决。 所有未使用的修补程序都会主动在其帐户中工作并报告其发现的内容。 我们确定优先级,通过命令分配,在早上不加批判。

再次运行测试,它们揭示了两个新的大问题。 并非所有服务策略都能正确到达,因此某些用户请求无法进行身份验证。 加上合作伙伴帐户的新问题。 我们急着看。

03:20。 紧急同步
修复了一个新问题。 第二,我们安排了紧急同步。 我们了解正在发生的事情:先前的修复解决了一个问题,但造成了另一个问题。 我们先休息一下,以找出正确无误的做法。

上午03:30 六只眼
我们知道什么是基础的最终状态,以便一切对所有合作伙伴都有利。 我们用6眼写一个请求,在预棒上滚动,在测试上滚动,在产品上滚动。

04:00。 一切正常
通过所有测试,看不到任何严重问题。 有时,团队无法解决某些问题,我们会迅速做出回应。 通常,警报是错误的。 但是有时无法到达某些地方,而无法在单独的页面上工作。 我们坐着,修理,修理,修理。 一个独立的团队启动了最后一个重要功能-计费。

04:30。 不可退的点
无回报的时刻临近了,也就是说,如果我们开始回滚,我们将无法满足给我们的停机时间。 帐单存在问题,帐单无所不包并会记账,但固执地不想从客户那里注销。 在各个页面,操作和状态上都有一些错误。 主要功能有效,所有测试均成功通过。 我们认为部署已经完成,我们不会回滚。

上午06:00 我们完全在用户界面中打开
错误已修复。 一些不受影响的用户留给以后使用。 我们向所有人打开界面。 我们会继续在计费方面引起人们的注意,等待用户的反馈和监控结果。

上午07:00 API加载问题
很明显,我们在API上有一些不正确的计划负载,并测试了该负载,这无法确定问题所在。 结果,约5%的请求失败。 我们正在动员,寻找原因。

帐单固执,也不想工作。 我们决定将其推迟到以后,以便以一种平静的方式进行更改。 也就是说,其中的所有资源都已累积,但客户的冲销并未通过。 当然,这是一个问题,但是与一般部署相比,它似乎并不重要。

08:00。 修正API
我们推出了针对负载的修复程序,失败了。 我们开始回家。

上午10点 全部
一切都是固定的。 在监控和客户安静的情况下,团队逐渐上床睡觉。 帐单仍然存在,我们明天将恢复。

然后,在白天会有一些发布会修复一些客户的日志,通知,返回代码和自定义代码。

因此,推广成功! 当然,它可能会更好,但是我们对尚不足以实现完美的结论。

合计


在积极准备推出的两个月内,完成了43项任务,时间从几个小时到几天不等。

推出期间:

  • 新的和更改的恶魔-5件,替换了2个整体;
  • 数据库内部的更改-我们所有包含用户数据的数据库中的6个都受到影响,从三个旧数据库到一个新数据库的卸载已完成;
  • 完全重做前端;
  • 抽取代码的数量-新代码33000行,测试中≈3000行代码,迁移代码≈5000行;
  • 所有数据都是完整的,没有一个客户的虚拟机遭受任何损失。 :)

良好部署的良好做法


在这种困难的情况下,我们受到他们的指导。 但是,总的来说,在任何部署过程中观察它们都是有用的。 但是,推广越难,他们扮演的角色就越大。

  1. 您需要做的第一件事是了解部署如何影响或影响用户。 会有停机时间吗? 如果是这样,那么停机时间是什么? 这将如何影响用户? 最好和最坏的情况是什么? 并关闭风险。
  2. 计划一切。 在每个阶段,您都需要了解部署的所有方面:
    • 代码交付;
    • 代码回滚;
    • 每次操作的时间;
    • 受影响的功能。
  3. 播放场景,直到明确所有推出阶段以及每个阶段的风险。 如有任何疑问,您可以休息一下,分别探索可疑的阶段。
  4. 如果可以帮助我们的用户,则每个阶段都可以并且应该得到改善。 例如,它将减少停机时间或消除一些风险。
  5. 测试回滚比测试代码交付重要得多。 有必要验证回滚的结果,系统将返回到其原始状态,并通过测试进行确认。
  6. 所有可以自动化的东西都必须自动化。 不能自动化的所有内容都必须预先写在备忘单上。
  7. 记录成功标准。 什么功能应该可用,什么时候可用? 如果这没有发生,请启动回滚计划。
  8. 最重要的是人。 每个人都应该知道自己在做什么,在推出过程中取决于他的行为的内容和内容。

而且,如果一言以蔽之,那么经过良好的计划和精心设计,您便可以推出您想要的任何东西,而不会对销售造成任何影响。 甚至影响您在生产中的所有服务。

Source: https://habr.com/ru/post/zh-CN453364/


All Articles