标签归档:研发管理

研发管理之生产环境的变更管理

2017 年,Amazon S3 服务在美国东部区域发生了大规模的故障,影响了许多依赖于 S3 的服务和应用。这次故障的根本原因是维护人员在执行一个操作时,错误地将更多的服务器脱机,这超过了系统设计的冗余容量,导致了该区域S3的部分子系统开始备份,进一步扩大了故障的影响。

2018 年 10 月 31 日 GitHub 通过官方博客发布了 2018 年 10 月 21 日「挂掉」的事件分析。GitHub 指出此次事件发生的原因是在 10 月 21 日 22:52UTC 进行日常维护——更换发生故障的 100G 光学设备时导致美国东海岸网络中心与美国东海岸数据中心之间的连接断开。更具体地 GitHub 分析,虽然两地的连接在 43 秒内恢复,但这次短暂的中断引发了一系列事件,这才导致了长达 24 小时 11 分钟的服务降级。

2020 年 7 月,Cloudflare 的 DNS 服务遭受了大规模的中断,影响了许多依赖其服务的网站。该故障的原因是 Cloudflare 的路由器中的一个错误配置。

以上是在网上搜索各大平台的故障描述,可以看到这些故障都是由于生产环境的变更导致的,有些是网络设备变更,有些是配置变更,有些是维护人员在线上执行了某个操作…… 如此种种。

这些问题最终都是开发人员通过系统化的建设,一个坑一个坑的填完了,但是当我们带着一个团队急速前进时,可能来不及做这些系统化的建设,此时通过流程对生产环境的变更进行管理,快速解决或规避一些问题以控制线上故障的出现。流程能保证的是我们做事的下限

在做生产环境变更管理流程之前一定要明晰生产环境的概念和范围,在团队内达成共识,然后再去做流程,以规避因为对生产环境的概念和范围不一致,导致的误解和乌龙。

1 生产环境的概念

生产环境,也称为「产品环境」或「线上环境」,是指实际运行并对外提供服务的环境。这个环境中的软件版本、配置和数据都应该是最新的、经过充分测试的,以保证系统的稳定性和性能。线上环境需要提供24小时不间断的服务。

一个应用或环境是否属于线上环境,主要取决于它是否直接对外提供服务。例如,如果一个应用接收并处理来自最终用户的请求,那么它就是线上环境的一部分。同样,如果一个环境中的数据被用于生产服务,那么这个环境也应该被视为线上环境。

通常,生产环境包括以下 4 个部分:

  • 硬件资源:例如服务器、网络设备、云服务中的硬件部分等;
  • 软件资源:包括操作系统、数据库、中间件、云服务中的软件部分等;
  • 应用程序:实际运行的业务代码和与之相关联的部分,如 CI/CD 工具;
  • 数据:实际的用户数据和业务数据。

定义了生产环境,从生产环境衍生出生产环境的变更。

2 生产环境变更的概念和分类

生产环境的变更是指在生产环境中对任何一部分进行的修改,包括应用程序的更新、配置的修改、硬件设施的更换等。而线上故障大多来源于生产环境的变更,对生产环境的变更进行管理和控制,在较大程度上可以减少对系统稳定性产生影响。

生产环境的变更从其组成出发,再加上外部流量,可以分为 5 类:

2.1 硬件资源变更

硬件资源变更主要包含所有与物理硬件和云服务硬件配置相关的更换、升级或维护。

  • 硬件规格调整:例如,升级处理器(CPU)、扩充内存(RAM)、更换硬盘等。
  • 网络设备更新:包括替换路由器、交换机或进行固件更新等。
  • 存储设备变动:磁盘扩容、存储设备更换等场景会包含在内。
  • 云服务硬件调整:如云计算服务中服务器规格的调整、增减虚拟机实例、增减 POD 数、网络设备变更等。

2.2 软件配置变更

软件配置变更涵盖了所有与操作系统、数据库、中间件以及云服务软件设置的修改。

  • 操作系统参数调整:比如,优化操作系统性能通过调整系统参数等。
  • 数据库设置变动:例如,数据库参数调整或修改索引,导致数据库负载提升甚至锁表导致的无法读写等线上事故。
  • 中间件配置更新:如修改消息队列的设置,调整缓存策略导致缓存穿越或者缓存雪崩等线上问题时有发生。
  • 云服务软件配置调整:包括了云服务的安全规则更新、网络配置变动等。

2.3 应用程序变更

应用程序变更主要包含了所有与业务代码和将业务代码发布到生产环境的 DevOps 工具的更改。

  • 代码变更:代码变更是我们最最常见的变更类型,主要是通过修改代码改变应用程序并通过发布系统发布到生产环境。这也是我们变更管理中风险最大的地方,因为变更的人,变更的位置和逻辑等都是不确定的。除了正常的发布变更,应用的回滚也是应用变更的回滚,因为其改动了线上的应用。实际中,代码变更在逻辑上包括了修复 bug、优化性能、增加新功能等,都需要对应用程序代码进行更新。
  • 配置变更:指应用系统的配置变更,一般是通过配置系统来变更,触发线上应用的热更新或滚动,配置如果是写死在代码中,会变为代码变更。
  • 依赖库更新:实际业务中需要对应用程序所依赖的库或框架进行更新,有些更新可能需要改代码,或者代码本身已经是这么个逻辑,在构建的时候就会带出去。
  • DevOps 工具变更:例如,升级工具版本,或者对某些功能进行调整。
  • DevOps 工具配置变更:如发布脚本中对于 dev 或 prod 环境的配置修改等等,都是高风险操作,线上有着血淋淋的故障。

2.4 数据变更

数据变更很少被人当作变更处理,因为很多时候就是正常的业务操作,如管理后台的批量操作这些,但是这些批量操作如果发生在高峰时期,可能会对线上业务带来较大的影响,轻则速度变慢,重则线上事故。数据变更可以分为线上数据的清理、迁移、更新等操作。

  • 数据清理:如定期删除过期数据,清理无效数据节省成本等等,基于不同的目的,将数据清除,除了可能会影响性能,如果清理错了,将会导致用户丢失,以至用户资产的损坏,这将会是很大的线上事故。
  • 数据迁移:如将数据从一个数据库迁移到另一个数据库,或者因为业务升级,数据需要从一种逻辑迁移到另一种逻辑,除了负载压力,更多的可能是数据错乱或者数据丢失,这两种情况都会引发用户投诉。
  • 数据更新:如前面说的管理后台批量更新,或者上线新模块在已有的数据库上初始化数据等等,这种最多的情况是其引发的 DB/ES 等存储类中间件的高负载导致服务的异常或引发线上事故。

2.5 流量变更

流量变更和上面四个类别不同,其是从外部来看的,主要包含了流量变化的情况。这里不考虑攻击类的流量。流量一般是带来高负载,或者由高负载引发的链路异常或雪崩,从而导致整体服务异常或线上事故。

  • 负载调整:如对调整负载均衡策略,更改流量路由等由于考虑不周引发某些节点过热或流量过大,引发级联反应,从而出现异常或事故。
  • 后台投放或大型促销活动:如没有提前通知的后台投放或大型促销活动、特殊事件导致的流量激增,可能需要进行负载调整或资源扩容等,如果某些链路存在容量上限,或者达到扩容的上限,就会引起线上异常或事故。

以上 5 种类型画成简单的脑图,如下:

图片

3 变更管理

变更管理是指以可控的方式对线上的服务、配置或基础设施进行变更,从而减少变更对业务和服务质量的影响,快速处理变更可能带来的问题,提升系统的稳定性。

变更管理,咱们从组织和流程机制两个方面来看。

3.1 组织

一个事情要想有力的执行下去,一定是有一个组织来保障事情的整体节奏和推进。

从组织的角度,整个变更管理的组织成员角色可以分为以下几种:

  • 变更管理主导者:一般来说,这个角色通常由技术团队的高级管理者来担任,并且这个事情它本身是一个从上向下的事情,需要更上层的负责人来推进事项,一般是 CTO 或 VP,或质量的负责人。他们需要确保变更管理策略和流程的成功实施,对整个变更管理过程负责,并需要对所有的变更决策拥有最后的决定权。

  • 变更管理委员会:这是一个跨部门的团队,包括来自业务、开发、运维、质量保证等部门的代表。他们的任务是评审即将进行的变更,评估其对业务的影响,以及是否符合公司的战略目标。他们还负责改进变更管理流程,并对变更管理的效果进行监督和评估。在实际的实施过程中可能没有正式的名称叫委员会,可能叫 XXX 质量小组,或者就是某个研发中心的管理团队兼任。

  • 变更经理:这个角色负责确保变更管理流程的日常运行,是实际的变更控制推进者,他们需要协调变更的执行,确保所有的变更都通过了必要的评审,已经准备好了回滚计划,并且变更后的效果已经得到了验证。在实际的实施过程中,变更经理大概率是某个 Leader 或者质量的负责人,或者 PM。

  • 变更执行人:这个角色负责协调变更的具体实施,例如安排变更的时间,通知相关人员,收集反馈,等等,一般这种变更由一线的开发,SRE 来做,也有大一些的公司有专门的职位。

3.2 流程机制

变更管理有一个理想状态的标准流程,其大概如下:

  1. 变更申请:在我们的流程中可能是创建发布记录,或者申请紧急发布
  2. 变更评审:变更评审主要是检查变更过程是否完备,以降低变更的风险,其包括如下内容:
    1. 就绪分析:材料是否完备,人员、设备、软件、网络是否就绪,测试是否达到上线要求等。
    2. 风险分析:架构、性能、业务、合规等方面的风险评估,变更内容是否属于需求范围,变更是否可控。
    3. 重要程度:变更属于一般、重要、紧急、标准哪一种。
    4. 变更审查:内容是否满足业务需求,内容是否通过测试,测试是否全面、有效。
    5. 应急管理:变更步骤、应急方案、回滚方案、应急预案是否完备。
    6. 变更实施:变更计划时间如何安排,发布及回退操作步骤是否完备,自动化步骤情况。
    7. 变更验证:变更涉及的业务、技术验证方法与时间安排。
  3. 变更审批:相关负责人对于变更评审的结果进行确认,并审批通过。
  4. 变更执行
    1. 根据发布计划执行发布操作,一般应该有一个灰度的过程;
    2. 验证线上功能并回归主流程;
    3. 持续灰度,观察用户直到灰度完成。
  5. 变更验收
    1. 对发布的功能进行验收,对于影响范围内的功能进行验收,对业务主流程进行回归验收;
    2. 留守,并观察日志、监控服务负载等,这个操作是为了及时发现验收检查漏掉的问题,或者及时处理隐藏的问题,以减少变更后产生的问题对线上业务的影响。

我们做这个流程是形式上的安慰,还是僵化的惯性,还是能真正地解决问题,是我们在做这个流程以及执行这个流程中需要着重思考的问题。

在变更前,即我们变更线上环境前需要自己做 Code Review,以及交叉的检查,以尽量减少问题流转到后面的操作中,节省问题的处理成本。

在标准流程之外,另外还有两个特别重要的点,一个是周知,一个是盘点。

周知在形式上可以是邮件、群通知、群消息,通过这些方式,将研发自己做的前面所定义的线上变更周知给相关方:「我们做了 XXX 操作,可能会影响 XXX ,你们看下对你们自己有没有影响,如果有相关告警可以找我。」

变更虽然有流程,但是流程保证的是过程,对于过程中的问题通过变更盘点的方式,阶段性回顾问题和成果,在变更委员会中达成共识并继续迭代。在每次迭代的时候我们可以问自己如下的一些问题:

  • 与上次回顾相比,变更对线上的影响有更严重吗?有影响到稳定性吗?
  • 变更流程是否有什么问题,是否需要专项来解决?是否应该解决?
  • 上次回顾安排的事项落实了吗,对应的情况如何,是否有更新到流程或系统中?

以上的回顾操作我们建议以某个管理系统来承载,并且这个管理系统是带有通知等功能,以更好的将变更相关的信息周知出去。当然,也可能直接共享文档+群通知来搞。

4 小结

上面的变更管理只是流程方面的,对于实际中变更管理最好是能在类似于 DevOps 系统中的落地,最少也是在项目管理或流程系统中落地。

生产环境的变更管理是一项复杂而重要的任务。通过对生产环境的良好理解,结合有效的组织、流程和系统工具,我们可以实现对生产环境变更的有效管理,保证业务的稳定运行,提升用户的使用体验,同时也提升了我们自身的运维效率和质量。这也是我们做研发管理必须要完成的任务之一。

测试左移到底移了什么?

说起测试左移,得从瀑布模型开始。

软件工程瀑布模型(waterfall model)概念,起源于 Winston Royce 发表于 1970 年的著名文章 “Managing the Developmentof Large Software Systems” (Proc. Westcon, IEEE CS Press, 1970, pp.328-339)。

虽然这个模型可能是个误会,可以见 Craig Larman 和 Victor Basili 教授在 2003 年发表于 IEEE Computer 杂志的封面文章 《Iterative and Incremental Development: A Brief History》 中为我们讲解了一段非常精彩的有关瀑布模型的历史故事,这也可以说是世界软件工程史最大的误解之一。

他其实一直倡导的是迭代、递增和演进式开发,他在那篇文章中描述的瀑布模型其实只是一种最简单的情况,并不是普遍适用的,现在看也不是一种先进、最佳的方案。

瀑布模型的生命周期,包括需求分析阶段、设计阶段、实现阶段和测试阶段等等,其中测试又可以分为单元测试、功能测试、系统集成测试等。

测试左移是在瀑布模型的基础上,为弥补瀑布模型的不足,不让测试工作只成为产品交付前的最后一道屏障,而将测试往前提,将测试贯穿于整个软件研发生命周期中。

这里为什么是左移呢,是因为我们大多数的阅读习惯是从左到右,左在前。当把整个传统软件生命周期在一条直线上辅平,从左到右分为是从需求分析阶段、设计阶段、实现阶段到测试阶段,所以当我们想把测试提前的时候,在这条直线上,就是往左移了。

测试左移一词(shift-left testing)最早可能出现在 Arthur Hicken 的博客里,在他的博客中提到了对测试左移的看法。见这里:The Shift-Left Approach to Software Testing

其依据的核心逻辑是随着软件进入生命周期的后段,发现一个问题并解决的成本会急剧地增加,如下图所示:

成本增加的原因可能有如下几种:

  • 关联方多:越后期,关联的模块越多,定位一个问题,解决一个问题需要联动的各方更多,成本显著增加;
  • 影响面大:后期影响范围更大,修复一个问题需要考虑的问题更多;
  • 流程拉长:当到测试甚至线上再出现问题,整个处理问题的流程拉长,从开发阶段的开发自我闭环,到测试阶段,测试和开发互动,到线上用户、客服、测试、产品和开发都要介入,其流程长度完全不一样。

从图上看,当左移后这些成本会显著减少。不仅仅是减少成本,还可以减少当出现质量问题时,归责于测试团队的问题,以及关于质量的责任问题的扯皮过程。在我们传统的研发过程中,测试同学处于一个被动接受需求,被动接收开发完的功能进行测试,能主动改变的事情不多,而往往背锅的时候都会有测试团队。

测试左移的核心逻辑或原则个人认为有以下三点:

  1. 开发同学是质量的第一负责人,测试同学是共同责任人并辅助开发同学做好质量工作;
  2. 预防 BUG 比发现 BUG 更重要,工作的重心是预防而非发现;
  3. 测试同学以一个相对外部的视角来提供质量建议以辅助开发同学做好异常处理,以提升开发同学的开发质量和技术能力,从而提升整体研发的效能。

在测试左移的研发流程中,测试同学有以下职责:

  1. 测试同学主动参与整个研发过程,从产品阶段的质量需求,到设计阶段的方案设计(测试人员往往对全局更加了解)等;
  2. 测试同学通过手工或者自动化的方式,对 prod、stage、fat 等环境的应用进行频繁的测试,而不用困在流程中等提测后再进行,更主动进行测试;
  3. 在流程中负责主流程的质量验证;
  4. 测试同学负责线上问题的跟进和闭环;

我们理想中把这种模式严格落地后,线上质量会提升并且开发同学的能力会有极大的增强。

这里可能会有同学提出关于人力成本的考虑,觉得把测试工作转嫁到了开发同学,或者觉得测试同学的思维模式是找问题,开发同学潜意识不愿意找,不愿意把自己写出的东西弄崩溃,认为需要有一个测试环节等等问题。

但是当开发是质量的第一责任人,并作为一个独立的主体,对自己开发的代码负责,对自己负责的应用负责时,会想办法来预防 BUG,提升质量,那些思维模式的问题会随之改变。

在我的职业生涯中也经历了几年自己开发,自己测试,自己发布的时光,感觉很爽,就是一点,特别谨慎(害怕),因为此时你会是一个独立的主体来解决问题,你得为你自己的代码质量买单,此时会想尽一切办法不出 BUG,预防 BUG,包括极度严谨的多次的 Code Review,每次都要走的多级灰度部署,验证,日志查看,留守。其导致的结果是在一个超过十亿 PV 的应用(中间还有大版本升级、基础环境的升级等大范围的操作)上两年没有出现过大的事故(当然有灰度过程中的问题,但是及时发现并解决)。

那么,作为一个技术团队管理者在开始践行测试左移时需要考虑什么?

  1. 团队是否适合做测试左移,测试左移对于开发同学的要求会比较高?
  2. 是一把梭,还是先试点,需要评估一下这个改动的影响范围,考虑灰度一下?
  3. 业务需要快还是慢,对于慢业务用传统的瀑布是否更合适一些?
  4. 左移到什么程度?

回到主题,测试左移到底移了什么?

我的理解,测试左移,移的是角色职责,移的是责任主体,移的是质量意识,这些不移,其它移了都会是事倍功半。