您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Model Center   Code  
会员   
   
 
     
   
 订阅
  捐助
大规模开发团队如何实现DevOps转型?
 
  4204  次浏览      16
 2018-3-20 
 
编辑推荐:
本文来自于作者付辉,文章中讲到功能与后端保障之间的权衡、从敏捷转型为DevOps、暴露控制、代码速率和分支、Agile on Steroids等。

微软全球开发平台工程团队从敏捷到DevOps的转型

2013年11月13日,我们宣布了Visual Studio2013,以及微软研发云Visual Studio Online (VSO) 的正式商用。紧接着我们经历了一次长达七小时的服务中断。我们的服务运行在一个“弹性扩展单元”中,为大约一百万用户提供服务。当时恰逢峰值流量时间段,欧洲和美国东西海岸的用户均已上线,在市场部门对外公布正式商用的同时,我们正在通过“功能开关”启用各种本被隐藏的新功能。随后发现负责服务间通信的IP端口,这个重要的网络层组件未能如期生成我们需要的遥测数据。当时因为新功能发布,已经产生了大量请求。从技术的角度来看,这造成了一个很尴尬的情况,如图1所示。当时的细节情况可以参阅这里。[i]

图1:VS 2013的发布因为VS Online服务一系列尴尬的中断而面临窘境。

从市场的角度来看,本次发布活动无疑是一个巨大的成功。VS Online服务借助这一转折点,成功地实现了两位数的用户数月增量。(增长的趋势还在继续,随后一年里,百万级别的用户数顺利翻倍。)

功能与后端保障之间的权衡

那段时间里,VSO只有一个托管在芝加哥数据中心内的弹性扩展单元。我们很清楚,需要通过多个单独部署的弹性扩展单元进行横向扩展,但我们总是更重视与功能有关的工作,忽略了使用多个弹性扩展单元为网站提供更周全的保障这件事情。发布会上遭遇的情况让我们改变了自己的想法。相关团队决定将本已计划好的功能改进工作延期,全力解决后端的保障工作。我们需要通过某种方式对VSO的后续更新进行“金丝雀部署“。原本使用的芝加哥弹性扩展单元(我们称之为SU1)保持不变,但我们打算在该弹性扩展单元之前增加另一个单元,新增的单元被命名为SU0。

在这一过程中,首先我们会将所有冲刺(sprint)版本部署至圣安东尼奥 (Scale Unit 0),在这个位置运行一段时间。如果感觉一切正常,才会将其滚动部署至芝加哥的单元 (Scale Unit 1),如图2所示。当然,如果SU0遇到问题,还可以修复问题并重新启动新一轮的部署。后来我们又在这个序列中加入了更多Azure数据中心。到2014年秋季,我们增加了阿姆斯特丹作为第五个数据中心。随着业务继续扩展至全球更多地区,很快我们还将加入澳大利亚。在以上过程中,我们都在使用Visual Studio Release Management来处理部署流程和自动化滚动更新等操作,每一个冲刺版本都是这样部署的。

图2:2013年11月之后,VSO从原本的一个数据中心扩展至多中心,借此实现“金丝雀”部署和全球落地。

对于线上环境服务质量的重视立刻获得了立竿见影的效果。从2014年4月服务月度点评(图3)中可以看到,2013年11月共出现了43个线上问题(LSI),六个月后骤降至7个,其中仅两个来自正式发布(非预览)的服务。我们还在持续完善自己的DevOps实践和运维实践,注重保持线上环境的健康状况,不过接下来还有很长的路要走。

 

图3:到2014年4月,VSO仅触发了7个LSI,六个月前这一数据还是43个。在这七个LSI中,只有两个是已经正式发布的服务造成的。

我们如何从敏捷转型为DevOps

七年来,微软全球开发平台工程团队 (Developer Division, DevDiv)一直在拥抱敏捷。借助切实可行的工程实践,我们从XP时代逐渐积累的技术债减少了15倍。我们为部门内部负责不同方向的团队和产品负责人提供Scrum培训,并将为客户提供价值作为一切的核心。在发布Visual Studio 2010时,该产品线获得了前所未见的客户认可。[ii]

发布VS2010之后,我们很确定是时候将Team Foundation Server转型为软件即服务 (SaaS)的研发云产品了。该服务的SaaS研发云最早被命名为 Visual Studio Online (VSO),现在已经改名为Visual Studio Team Services(VSTS) 研发云,托管于Microsoft Azure (不过在我们工程团队内部还是习惯使用VSO来称呼这个产品)。为了继续延续之前的成功,我们需要开始采用更多的DevOps实践,这也意味着我们需要将实践从敏捷转型为DevOps。这两者有何差别?

DevOps文化的特点之一在于需要从使用中学习经验。对于敏捷,有一种心照不宣的假设,认为产品负责人是无所不知的,能够正确提出产品的规划和新的需求列表。与之相反,在运行某种高度可靠的服务时,你可以用近乎实时的方式观察用户是如何使用不同功能的。你可以更频繁地发布新版,通过实验进一步完善,衡量并询问客户对不同改变的看法。这一过程中所收集的数据将成为后续一系列改进的依据。通过这种方式,DevOps产品的需求列表实际上是一系列假设,最终会变为软件运行过程中所做的实验,并可促成持续不断的反馈循环。

如图4所示,从敏捷中催生出的DevOps基于四大趋势:

图4:这四大趋势推动了DevOps的演变。

与很多“生于云端”的公司不同,我们最开始并没有SaaS产品,客户主要在PC端本地环境中使用我们的软件(Team Foundation Server最初发布于2005年,现已发布了2017版)。在开发VS Online,也就是现在的VSTS研发云时,我们决定为SaaS和“盒装”版本的产品维护同一个代码库,但采取云为先的开发策略。工程师在推送代码后将触发持续集成流程。当为期三周的冲刺结束后,我们会发布到云端,进行4-5个冲刺后,会为“盒装”产品发布一个季度更新,过程如图5所示。

图5:我们为VSTS研发云(SaaS产品)和TFS(本地运行产品)使用了同一个代码库。每三周,我们会将新功能部署至VSTS研发云。每季度,这些更新会滚动发布至TFS。在发布重大TFS更新,如2015版时,则会基于当时VSTS研发云的版本进行。

暴露控制

在开发服务的过程中,高频率发布会让我们获益匪浅。在我们的工作中,我们会在为期三周的冲刺结束后发布。借此我们可以更及时地将工作成果展现给用户,但我们需要对暴露的时机进行一定的控制。这方面我们遇到了一些问题:

l 如何处理需要多次冲刺才能完成的功能?

l 如果明确知道某个功能随后需要改动,又该如何针对不同功能进行实验以便了解使用情况和用户反馈?

l 如何通过“灰度上线”在做好对外发布和公开推广之前引入新的服务或功能?

对于所有这些问题,我们选择了功能开关这种模式。功能开关是一种控制机制,决定了要将何种功能暴露给哪些用户或用户组。随着团队针对新功能开展工作,我们可以通过功能开关服务注册一个开关,这种开关默认处于关闭状态。在准备好让某些用户尝试新的功能后,即可为这些用户在生产环境中打开对应的开关,并根据需要决定何时关闭。如果要改动对应的功能,无需重新部署即可关闭这个开关,停止该功能的对外暴露。

通过这种方式实现渐进式的暴露控制,功能开关还提供了一种供我们在生产环境中进行测试的好方法。通常一开始我们会将新功能暴露给内部员工,随后暴露给早期用户,随后逐步暴露给更广泛的客户群体。通过对性能和使用情况进行监控,可以确保新的服务组件在大规模环境中可以正常无障碍运行。

代码速率和分支

当我们于2008年首次采用敏捷开发时,我们认为可以通过适当的质量门禁 (Quality gate) 和代码分支结构开发出更高质量的代码。早期的开发工作会使用一些异常复杂的代码分支结构,只能接受按照严格定义编写的代码,通过封闭签入(gated checkin)机制,确保新提交的代码必须和主干代码完成预合并,并经过构建策略的检查后才能真正进入配置库。

这种代码分支结构造成了一种始料未及的后果:很多时候我们需要花费数周甚至数月的时间才能把叶子分支上的代码逐层合并进入主干。而分支中的代码将长时间处于未合并状态,这又会为合并工作造成大量遗留债务。当工作成果已经准备好进行合并后,主干可能已经进行了大幅度的改动,导致出现合并冲突,进而需要花费大量人力物力进行协调。

2010年,我们采取的第一个措施是将代码分支结构大幅“压平”,仅保留很少的分支,并且保留的分支大部分也是临时的。我们明确了目标,要优化代码流动速度,换句话说,就是将代码签入和可被其他人获取的间隔时间降至最低。

随后我们使用Git打造了一个分布式版本控制系统,该系统目前也已被VSTS研发云和TFS所支持。我们的大部分客户和同事依然在使用集中化的版本控制系统,因此VSTS研发云和TFS可以同时支持这两种模式。Git的优势在于可以实现非常轻量级的临时分支。我们可以为工作项创建特性分支,并在将变更合并到代码主干后进行立即清理掉该特性分支。

提交后的所有代码位于Master(主干)中,同时Pull-request工作流结合了代码审阅和质量门禁功能。借助这些能力,代码合并工作已经可以通过简单的小批次操作持续进行,每个人随时都可以看到最新的代码。

这种流程可以在短时间内对不同开发者的工作进行隔离,随后以持续的方式集成在一起。这种临时分支还降低了后期维护的开销,可在不需要时彻底删除。

Agile on Steroids

我们依然在遵循Scrum的原则,但为了促进交流和跨地域扩展,只保留了其中的精髓。例如我们工作主要以功能小组 (Feature crew) 为单位,这类似于Scrum中团队的概念,但产品负责人需要加入团队并参加所有日常工作。产品负责人和工程主管联手代表整个团队。

我们还运用了团队自治和组织整合 (Organizational alignment) 的原则,借此功能小组中产生了新的变化。团队往往涉及多个领域,我们通过整合开发人员和测试人员的职业晋升路径将这两个角色统一成了一个工程角色(此举大幅提升了士气)。

所有团队都是内聚的。每个小组有8-12名工程师,我们会尽可能确保他们至少可以共同工作12–18个月,很多团队的合作时间甚至更长。如果因为工作原因需要调整,我们会建立第二个小组来处理积压的工作,而不会让工程师在不同小组间来回更替。每个功能小组都有自己的团队办公室,如图6所示。这样的办公室并不是那种大面积开放式空间,而是一个专属的房间,可供大家针对同一个领域开展工作并自如地交流。团队办公室旁边还为可能的突发情况准备了小的“焦点办公室 (Focus Room)”,这种办公室中,我们也非常鼓励自由的交流。到了每日站立会议时间时,大家都会站起来畅所欲言。

图6:在同一个团队办公室中干活的功能小组成员。

根据经验,我们最终选择以三周为一个冲刺周期。事实证明对于我们这种需要全球协作的任务,很难在更短的时间里为客户提供足够多的价值,而如果选择更长的周期,则会影响新功能的发布速度。微软内部一些部门以两周为一个冲刺周期,但也有一些部门甚至会每天多次针对新工作成果展开各种实验,不会受到冲刺的约束。

从概念上来看,“完工”的定义其实很好理解。构建,运行,这样就行了。当一次冲刺结束后,你的代码会正式部署给数百万用户,如果代码中存在任何问题,你(以及其他每个人)立刻就能知道,并可立即开始修复问题根源。

我们会轮流担任ScrumMaster 这个角色,这样每个人都有机会体验Scrum Master的管理责任。在对外交流方面,我们会让冲刺的仪式 (Ceremony) 尽可能简洁。每次冲刺开始时,队员从产品积压工作列表 (Product Backlog)中领取任务,并通过一封篇幅不超过一页的邮件就自己的冲刺计划进行描述,邮件中需要添加指向VSTS研发云中产品积压工作列表内容(PBI)的超级链接。大家可以通过回复这封邮件的方式共同对冲刺进行审阅,同时,团队还会提供一个大约三分钟左右时长的视频。视频中包含演示,会从客户的角度介绍通过本次冲刺所能实现的目的。

我们还会确保计划尽可能简单。通常来说,会针对未来18个月的工作制定愿景,并朝着这个方向努力。愿景可以通过多种形式体现,例如技术尖峰 (Spike)、故事板 (Storyboard)、概念视频,以及概括性文档。我们以每6个月为一季,“春季”或“秋季”,在这段时间内我们会围绕整个团队的承诺和依赖关系坚持不懈地完成工作。每三次冲刺后,功能小组的领导者会聚在一起进行一次“功能沟通会”,借此分享希望达到的优先级,修正后续工作方向,与其他团队交流寻求新的目标并确保所有团队保持一致。例如可以使用功能沟通会重新对网站工作和用户可见的功能进行划分。

构建—度量—学习

在经典敏捷实践中,由产品负责人对产品积压工作项 (PBI) 进行优先级排序,大家会或多或少地将其视作一种需求。PBI 可能体现为用户故事,形式可能非常简单,但必须是确定无误的。我们以前就是这样工作的。

但现在不是了。为了遵循DevOps实践,我们会将PBI视作“假设”。这些假设必须能转化为实验,借此获得能够支撑或减少实验的证据,随后,我们还可以从这些证据中学到切实可行的经验。[iii]

进行一个足够好的实验,要求有具备统计学意义的样本,同时还有用于对照的控制组,此外还需要理解不同因素的影响结果。例如图7中的这个例子,我们遇到了一个问题:VSTS研发云的新用户并没有立刻创建团队项目,而没创建团队项目会导致用户无法执行其他绝大部分操作。图7展示了在网页上开始创建团队项目时的界面。

图7:原本的方法需要执行太多操作,并且很容易让用户分心,很多用户希望能以更自然的操作来创建项目。

我们修改了Web端和IDE中的这部分体验。图8显示了IDE中的新体验,该体验会鼓励用户通过两个界面注册VSTS研发云并建立项目。我们借助六个弹性扩展单元中的两个对这个新体验进行了实验。

图8:在两个弹性扩展单位中为IDE实现了更完善的项目创建体验实验。

这次IDE实验的影响如图9所示。新客户创建团队项目的比例由3%增长至20%(增幅约七倍)!

图9:IDE中的流程变动让新用户通过IDE创建项目的比例从3%增长至20%。

于此同时,我们还改进了Web界面的注册过程,也获得了非常明显的效果。图10展示了Web注册所做的改动。

图10:Web注册通过类似的简化可以在第二个界面上直接建立项目。

我们统计了在注册帐户当天就建立了团队项目的用户比例。这一比例从原本的约18%增长至30%(约1.7倍),如图11中从绿色过渡至黄色的柱状条所示。虽然结果喜人,但其实这一结果与我们预期相差较远,同时与IDE方面的所取得的大幅提升之间有很大的差距。

图11:Web帐户创建的结果由于两个实验出乎意料的相互干扰而被误导。排除这些因素后,结果就很清楚了。

后续调查中发现,我们其实还在同一时间进行了另一个实验。在这个实验中,位于漏斗顶端很多不符合要求的用户也被鼓励注册帐户,但他们并未这样做。这也证明了我们的控制组不够完善,两个实验相互之间产生了干扰。在停止了用于加速创建帐户的实验后,项目创建比例激增至50%,如图中绿色柱状图所示(增加2.8倍,比IDE中的效果还要好2.5倍)。

这个故事的寓意在于,实验的执行过程有好有坏,并不能总是很明显地确定结果是否合理,是否可重现,以及是否受到了妥善的控制。

   
4204 次浏览       16
相关文章

DevOps转型融入到企业文化
DevOps 能力模型、演进及案例剖析
基于 DevOps 理念的私有 PaaS 平台实践
微软开发团队的DevOps实践启示
相关文档

DevOps驱动应用运维变革与创新
运维管理规划
如何实现企业应用部署自动化
运维自动化实践之路
相关课程

自动化运维工具(基于DevOps)
互联网运维与DevOps
MySQL性能优化及运维培训
IT系统运维管理