时值2012年,Netflix正在勉力支撑自身关键服务运维。整个部署过程,就如穿越泥潭般费时费力。金丝雀测试只能用于考查持续能力(「只要连续一周不出问题,就推进至下一步」),而非真正验证功能的正确性。研究问题就如皮球一般在不同团队间被踢来踢去,而且人们很难找到问题的根本原因,更遑论阻止这种踢皮球现象。很明显,这一切都需要得到改变与纠正。
时间快速推进至2018年,Netflix如今已经拥有1.25亿全球会员,每天视频内容播放量超过1.4亿小时。我们在改善工程团队的开发与运维方面投入了大量资金。在这一过程中,我们尝试了多种服务构建与运维方法。在今天的文章中,我们希望分享一种在Netflix内部较为常见的解决方法,同时探讨其优势与缺点。希望这一经验分享能够激励更多朋友勾勒出替代性方案,同时从我们的经历中总结出心得与教训。
一支队伍的发展旅程
Edge Engineering负责AWS服务中的第一层,这些服务正是Netflix媒体流得以顺利运转的前提性基础。过去,Edge Engineering团队拥有众多以运维为重点的SRE,他们主要负责软件生命周期当中的部署+运维+支持部分。而新功能的发布,意味着开发人员需要与运维团队共同就指标、警报以及容量相关问题开展协调,而后由运维团队进行代码分发以实现部署及运营。为了高效推动代码运行以及合作伙伴支持,运维团队需要建立持续性培训制度以确保人员理解新功能并修复各类bug。总体来讲,建立起独立运营团队的主要助益,在于当一切进展顺利时,开发人员不致因运维任务的介入而分神。
然而,当工作进展遭遇阻碍时,成本就会快速叠加起来。开发人员与SRE之间的沟通与知识转移往往存在严重损耗,且需要额外的往来以实现问题调试或解答合作伙伴的疑问。由于运维团队对需要部署的变更本身缺少直接了解,因此问题部署通过会带来更长的检测与解决周期。当时在代码完成到部署之间的时间断档要远远长于当前,发布时长往往需要数周而非数天。这方面反馈主要来源运维人员,他们大多亲身经历过诸如警报/监控缺失或者性能问题以及延迟增加等挑战,而这些问题最终又会被转移至开发人员手中。
为了改进这一点,Edge Engineering团队尝试了一种新的混合模式,即开发人员可以在需要时自行推送代码,同时在非工作时间内负责生产问题与支持请求。这种方式改善了开发人员的反馈与学习周期,但仍存在部分职责性空白。举例来说,尽管开发人员可以自行部署并调试整个代码发布流程,但一般仍会遵循运营发布专家的意见。对于这些以运维为关注重点的人员,他们更有动力完成自己的日常工作,但却很难确定具体事务的自动化优先级——毕竟一旦体系明确,企业可能将不再需要他们这类职能角色。
为了找到更好的解决方法,我们决定退后一步,以基本原则作为起点——即我们希望实现什么,以及我们为什么未能成功。
软件生命周期
软件生命周期的目标在于优化“价值实现时间”; 有效地将想法转化为能够交付给客户的工作产品及服务。软件服务的开发与运行涉及一整套职能体系:
我们一直在对上述职能进行分割。在极端情况下,这意味着不同人员/角色将拥有与之对应的各职能区划:
这些专业角色可以在各个细分区划内实现效率,同时亦有可能在整体生命周期中带来低效率因素。专业人士立足单一重点领域发展自身专业知识,并持续优化该领域中的需求——换言之,他们能够更有效地解决自身难题。但软件需要经由整个生命周期才能为客户创造价值,而仅拥有自身生命周期片段的专家团队有可能建立孤岛,最终减缓端到端推进速度。在这方面,将众多不同专家引入同一团队将有助于减少孤岛,但同时也有可能增加沟通成本、引发瓶颈并影响到反馈循环的有效性。
谁构建、谁运维
为了重新审视我们的方法,我们从DevOps运动的基本原则中汲取灵感。我们希望通过打破孤岛并鼓励共享完整软件生命周期归属的方式优化学习与反馈效果:
“谁构建,谁运维”这一理念旨在鼓励系统开发团队同时负责系统的运维与支持工作,从而真正将DevOps引入实践。将此类责任分配给各个开发团队——而不再将其视为外部事务,有助于建立起直接的反馈循环并协调激励制度。在运维过程中遇到问题的团队,将有权通过改变自身系统设计或代码的方式修复问题; 他们将同时肩负起这两项职能。如此一来,每一支开发团队都将拥有自己的部署问题、性能错误、容量规划、警报缺失以及合作伙伴支持等解决目标。
通过开发者工具推动规模扩展
完整开发生命周期的归属权大大提高了软件开发人员的工作预期。为了帮助他们实现预期,简化并以自动化方式协同开发必要的工具就成了下一项重要任务。举例来说,如果软件开发人员期望管理服务回滚工作,则需要为其提供丰富的工具以检测问题并加以提醒,最终帮助其更轻松地完成回滚操作。
Netflix建立起多支中央团队(包括云平台、性能与可靠性工程、工程工具等等),其任务在于开发出通用型工具与基础设施,从而解决各个开发团队所面临的现实问题。这些中央团队将自身专业知识转化为可复用的基本组件,从而尽可能加强其他工作人员的任务处理能力。例如:
借助这些工具,开发团队将能够专注于解决特定产品领域中的实际问题。随着其它工具需求的出现,这些中央团队会评估多支开发团队之间的需求是否存在共性。如果是,那么其将对这些需求进行合并。有时候,某些实际需求太过具体,因此无法进行集中投资。在这种情况下,开发团队需要判断其需求是否足够重要,从而引导其自行着手解决。
在我们的这套新方案中,最棘手的问题之一就是如何立足此类问题平衡团队具体投入与中央投入。根据我们的经验,帮助开发人员获得创新型解决方案的收益,要高于由各团队分别自行建立解决方案的风险——毕竟此类解决方案在使用中还将持续迭代,因此在初始阶段加以控制有助于后续管理。在这项工作中,沟通与协调成为决定成败的关键。通过根据需求及各团队间的潜在共性进行调整,我们将能够更好地将投资与Netflix内部开发团队的各自优势相匹配。
完整周期开发人员
通过将上述思路结合在一起,我们构建起一套新的模式——其中开发团队配备有令人惊叹的开发者生产力工具,并直接负责完整的软件生命周期:设计、开发、测试、部署、运维以及支持皆在其中。
全周期开发人员应当在软件生命周期的所有区划之内皆拥有丰富的知识与出色的执行效率。对于很多初到Netflix的新任开发人员而言,这意味着他们需要面对大量自己从未接触甚至关注过的领域。我们通过开发训练营及其它多种持续培训形式向其传授知识并培养相关技能。知识非常重要,但单凭知识还远远不够; 我们还发布了多种用于部署管道(例如Spinnaker)与监控(例如Atlas)的高易用性工具,从而真正实现全周期归属的预期效能。
全周期开发人员将工程技术知识应用于生命周期的全部领域当中。他们从开发人员的角度评估问题,并提出诸如“如何以自动化方式运维系统所需要的内容?”以及“哪些自助服务工具能够帮助合作伙伴自行回答问题,而无需我的参与?”等问题。我们的团队通过这种方式逐步将以人为关注点的思维转换为以系统为关注点,并尽可能通过自动化——而非手动方法——实现规模扩展。
必须承认,向完整周期开发人员模式的转化要求我们对固有思维方式发起挑战。一部分开发人员将设计+开发(有时也包括测试)视为自身创造价值的主要方式。在这样的出发点之下,他们会将运营问题视为需要分心的“杂事”、过分关注能够短期解决的运维修复及支持问题,从而尽快回归自己的“真正工作内容”。但事实恰恰相反,全周期开发人员的“真正工作内容”在于利用自己的软件开发专业知识来解决整个生命周期中出现的问题。完整周期开发人员应该像软件工程师(简称SWE)、软件开发测试工程师(简称SDET)以及站点可靠性工程师(简称SRE)一样思考与行动。有时候他们会创建能够解决业务问题的软件,有时候他们会为此编写测试用例,有时候他们也会对系统的运维流程进行自动化设计。
要确保这种模式取得成功,各团队必须致力于实现由此带来的价值,并深刻意识到其中的成本因素。各团队需要配备适当的人员,并提供充足的空间以管理构建及部署工作、处理生产问题并响应合作伙伴的支持请求。此外,各团队还需要划定时间以组织培训、利用并投资各类工具,并与中央团队建立合作伙伴关系以建立可复用的组件与解决方案。在规划与审查期间,各团队还需要考虑生命周期中的各个方面,并将自动化警报响应与自助式合作伙伴支持工具等投资项目与业务项目共同列为优先事务。通过这种妥帖的人员配备、优先级设置与合作伙伴关系确立,各团队才能真正成功地运维自身构建的内容。而如果缺少这些必要条件,团队必将面临强度过大以及态度倦怠的风险。
此外,要在Netflix之外的环境中使用这种模式,大家必须对其做出调整。你的开发团队可能与我们一样面临着对持续交付管道以及监控/可观察性的需求,但大多数企业并不像Netflix这样具备中央团队投资人员,也不需要实现像Netflix这样的大规模、高复杂度业务体系。Netflix的工具通常是开源的,因此大家不妨将其视为做出初步试水的选项; 但在进一步熟悉自身情况后,大家也可以选择其它开源及SaaS解决方案以满足实际需求。你可以首先分析潜在价值并计算成本,而后推动思维方式转变。接下来,大家可以评估自身需求并确保以最低复杂性方式引入必要的新元素。
权衡
技术行业上存在着多种能够解决开发与运营需求的方法(详见DevOps拓扑中的具体清单)。其中描述的完整周期模式在Netflix内部非常常见,但也存在着一定缺点。因此,在选择模式之前,大家应当了解必要的权衡因素以尽可能提高成功机率。
利用完整周期模式,你能够利用各类工具对更为广泛的职能区划进行归属权与有效性考量。当然,这种广泛性需要多种技术及能力作为支撑。一部分开发人员更希望专注于成为特定领域中的顶级专家,而技术行业也确实需要这样的专才型从业者。对于这部分员工来讲,在各个区划内都具备一定了解与积累可能会干扰其工作节奏,甚至引发强烈的不满情绪。Netflix也有很多员工更希望深入钻研某一专业知识领域,而不愿花时间提高涵盖广度——我们也支持他们扮演这样的角色,并选择其他愿意接纳并享受广泛职能设定的员工参与到新模式中来。
根据我们以往立足云端的系统构建与运行经验,我们已经意识到广度型开发人员所能表现出的巨大执行效能。当然,必须承认这种广度的增加会提高每一位开发人员的认知负荷,这意味着各团队每周都需要平衡更多优先级调整建议,而不能单纯只关注某一领域。我们通过轮调的方式缓解这一问题,即由开发人员轮流处理部署+运营+支持的职能。这种方式同样具有两面性:如果处理得当,那么他们将为其他员工创造出空间以集中精力处理对深度要求更高的工作; 但如果处理不当,那么团队会被迫要求每个人参与到生产运营这类高强度工作当中,并引发整体性的倦怠情绪。
工具与自动化方案的引入有助于扩展专业知识,但没有哪款工具能够全面解决开发人员在生产力与运营领域中面临的每一个问题。Netflix在这方面拥有一整套用于“铺平道路”的工具与实践,并由中央团队提供官方支持。我们不会强制员工采用这些预设方法,而是希望通过用成效说话——即充分证明在利用这些技术之后,员工的开发与运维体验将远高于以往。这种方法的缺点在于,“各个团队所使用的每款工具中的每一项功能,都能满足他们最为核心的需求”这一终极诉求几乎不可能真正实现。因此,中央团队在解决方案开发方面的投资回报保障工作往往需要耗费大量精力与持续调整。
总结
从2012年到今天,我们的发展道路充满了实验、学习与转变。Edge Engineering项目的早期经验推动我们找到了更理想的模式,而这套模式也被积极应用于目前的全周期开发人员模式。当下,我们的部署成为一项常规且频繁的工作,金丝雀测试只需要数小时——而非数天——即可完成,开发人员能够快速研究问题并着手修改——不必再进行跨团队沟通。其它团队也切身体会到了这种新模式的优势所在。然而,我们很清楚这一切成就都离不开摸索过程中的不断学习与调整。我们也相信未来的需求还将提出更多挑战,而这些挑战必将成为我们进一步发展的核心动力。