从外部视角来看,整个行业的发展趋势肯定是趋于云原生的;从内部视角来看,云原生对研发人员和运维人员其实是一个不小的挑战。与云原生并行甚至更早的一个侧重于研发的方向是DevOps体系的建设。
关于DevOps,我们会听到各种声音:DevOps就是研发人员要懂运维,DevOps就是自动化运维,DevOps就是敏捷开发,DevOps就是一种理念。站在不同的角度,大家对DevOps的解读确实仁者见仁、智者见智。
我们引用百度对DevOps的定义。
DevOps(Development和Operations的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(Quality Assurance,QA)部门之间的沟通、协作与整合。它是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。通过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
图3-2 DevOps交集图
DevOps的出现是由于软件行业日益清晰地认识到:为了按时交付软件产品和服务,开发和运维工作必须紧密合作。DevOps是软件工程、技术运营、质量保障3者的交集,如图3-2所示。
传统的软件组织基本都是按照职能划分的职能型组织。项目管理、软件开发、测试、运维都是不同的职能部门,负责软件生命周期的某一项垂直环节。大部分软件的编码迭代是由开发工程师主导,但是上线发布及线上问题的运营工作往往交给了运维人员。
垂直的分工方式并非不好,而是当高频的发布与部署出现时,明确的局部分工反而会降低组织整体生产力。当发布从每周2次到每周上百次、上千次时,很难保证流水的线式发布能够正常高效,某个重要的需求可能会导致测试或运维资源吃紧,进而影响项目整体的吞吐量。同时,由于不同部门的组织目标不一致,因此会导致“组织深井”更加明显,从而减慢了IT交付业务价值的速度。
在DevOps模式下,开发团队和运维团队都不再是孤立的。有时,这两个团队会合并成为一个大团队,工程师会在应用程序的整个生命周期内紧密协作,开发出一系列不限于单一职能的技能。有的公司可能不会做组织的调整,但是会重新定义职责和岗位,让开发工程师具备开发、质量、运维的意识,除了开发代码外,还要自己做单元测试,甚至自测回归,最后自己上线发布、线上验证。线上问题也是开发工程师第一时间收到报警,根据日志、链路追踪等工具定位分析问题,重新修复问题并上线。
所有的问题都交给开发工程师做了,那运维工程师和质量工程师做什么?我们可以看到,开发工程师的职责变大的前提是他们有了更多工具和平台。如同前两年非常火的中台一样,一线的“士兵”可以随时呼唤炮火,这些炮火是怎么来的呢?往往就是由DevOps团队或者运维质量工程师构建的。当年,阿里进行DevOps调整时,原来的技术保障团队全部开始学习编程,后来转战阿里云,最终成就了今天面向中小企业的优秀基础设施。
DevOps看起来大大缩短了软件开发的周期,我们来分析一下它有什么优势。
DevOps模式使开发工程师拥有更多的工具和自主权,可以更快捷地完成开发、测试、部署、验证等工作。相比于传统开发模式下的跨团队沟通和多层审批,整个过程降低了许多不必要的冲突和沟通噪声,变得非常扁平,进而大大提升了交付速度。
之前线上故障的修复链路是一线业务人员发现问题并通过即时通信工具找到开发工程师,开发工程师再找运维团队去定位和修复。这样的沟通路径和修复链路很长,同时会存在沟通不到位的情况。
在DevOps模式下,丰富的工具会让线上问题的暴露更加提前,定位问题和修复问题也更加及时,线上版本的发布与回退也更加便捷。开发工程师可以随时拉一个Bugfix分支快速自测上线,不用因等着多方审批而“贻误战机”。
近几年,比较热的一个词是“质量左移”。在DevOps模式下,开发工程师能够更早地在上线前做用例验证、安全验证、灰度验证、AB测试,这样一来,线上的产品问题会更早地暴露在测试环境中或上线前,相当于运维的工作前置或左移,这样的模式能够大大提高产品质量。
DevOps其实更是一种文化,这种文化强调Owner意识,打破组织的束缚,开发团队和运营团队更加密切地合作,共同承担责任,将各自的工作流程相互融合。这有助于减少效率低下的工作,同时节约大家的时间。
DevOps的种种优势,使其逐步成为各个互联网公司争相采用的一种模式。
回到2018年,我们从整个研发生期来看自如当时的研发生产过程,如图3-3所示。
图3-3 研发过程图
·需求阶段:需求的管理曾经是杂乱无章的,需求由业务方录入Jira,但是对于业务人员而言,Jira的使用略微复杂,进而造成Jira上的数据正确率很低,往往没有完整的需求池。
·产品阶段:产品设计阶段一般作为对接开发的直接上层阶段,会有多轮的PRD(Product Requirement Document,产品需求文档)评审,梳理清楚产品需求,产品评审通过,测试工程师进行测试用例的编写,开发工程师进入架构设计阶段。这个环节当时并没有统一的工具和平台进行管理。
·开发阶段:开发阶段是整个需求交付生命周期中最长也是最重要的环节,这个阶段开发工程师会申请代码环境、机器资源(域名、服务器地址、数据库地址、中间件信息等)、权限,然后进行编码开发。这里与运维工程师的交互较多。
·测试阶段:开发完毕后会进入第二个重要阶段——测试阶段。这个阶段会进行多轮Bug修复与重新提测。通过测试环境验证后,还有一个准生产环境,开发工程师会手动合并代码到主干并进入待发布状态,准生产环境的代码对应主干的代码。很显然,这个过程极易造成手工错误。
·发布阶段:发布阶段会进入生产环境,进入生产环境阶段前需要测试工程师进行签发,签发后运维工程师操作工具从GitLab的主干分支拉取代码到打包机进行编译,打包机编译后的代码由SVN管理,生产环境再从SVN拉取class文件并重启发布。
从现在的视角来看,图3-3的发布和部署过程中的“低效点”非常多,我们来分析几个典型的差距。
·需求产品管理混乱:没有统一的工具和流程进行标准化的BRD、PRD管理,导致上游需求可能非常易变和不透明。
·人工交互过多,自动化程度低:申请资源、申请权限、提测、签发都要有人工交互,上线发布的过程更多地转移到了线下,效率不高,沟通成本很大。同时,代码的合并、资源的配置都是线下开发工程师手工操作,出问题的概率极大。
·工具薄弱:分支管理、环境管理混乱,GitLab和SVN两种代码协同工具并存,定位不清,流程冗长,导致运维成本急剧上升。
·系统脆弱性大:整个交付链路过长,环节层层相扣,一旦出现一个脆弱环节,就很容易导致整个流程阻滞。
系统和流程层面的问题其实都是冰山上面可见的部分,冰山底下的差距是人的差距。人的差距反映在两个层面:能力和思维。
大部分开发人员都只聚焦于业务开发,虽然对常用的开发技术栈很熟悉,但是对于技术背后的原理探索甚少,对于底层用到的基础设施和技术平台背后的知识接触得就更少了。有些工程师对于DNS(Domain Name System,域名系统)、Nginx毫无经验,甚至有些开发人员连Host都不会配置。
开发人员能力不足主要有两方面的原因:一是接触的场景太少,以JVM知识为例,我们面试时经常会问底层的垃圾回收算法、内存的分代、垃圾收集器、常用的定位JVM问题的命令等,但是实际上,在生产环境中能够接触这些场景,真正定位问题的机会极其稀少;二是主动性不足,一个开发工程师能力的高低,很大程度上取决于他愿不愿意去提升自己的能力。意愿和态度比能力现状更重要,这也是我们要讲的第二个层面——思维。
无论是开发工程师、测试工程师还是运维工程师,岗位名称有时候限制了大家的思维方式,思维方式被限制之后,对应的行动就会有所制约。开发工程师会把与服务器操作的工作留给运维工程师,运维工程师会把开发的工作留给开发工程师,双方分工明确。相反,如果我们的思维是成长性思维,是积极主动的,当我们搞不明白CDN和DNS的区别时,就会去查域名解析后的完整交互路径。大公司一般都有成熟的技术论坛、线上学习资源,但是一个只知道做业务的员工和一个不给自己设限的员工两者之间的差异是巨大的。
自如当时的研发团队和运维团队也是同样的情况,各人自扫门前雪,对于边界不清晰的工作,往往会有说不清、扯皮多的问题。开发工程师和运维工程师的能力水平与二线互联网公司也有巨大的差距,运维工作尤甚,大家还是以比较传统的手工运维为主,加班成为常态,整个团队疲于应对各种低端、重复的故障。
基于以上几个问题的剖析,我们开始重设方向,决心打造DevOps体系,帮助自如的产品研发流程走向一个新的阶段。如何改变这些差距呢,我分析了研发效能的效率飞轮,如图3-4所示。
图3-4 效率飞轮图
研发(运维)人员能力变强,才能构建更加成熟、健壮的工具和平台;工具和平台更加健壮,能够大大提升研发人员响应问题、处理问题的效率;快速处理完问题,能够使研发人员有更多的时间去学习和迭代新的技能。研发人员的能力越来越强,整个研发组织的效率会螺旋式上升,这样研发效能的效率飞轮就飞速转了起来。
通过对开发能力的差距分析,我们横向剖析了开发交付过程中的几个阶段,同时调研了阿里的云效、腾讯的Coding平台和TAPD(Tencent Agile Product Development,腾讯敏捷协作平台)。这几个工具非常成熟,由于自如当时没有上云,因此也无法直接使用,只能基于现状。像云效这样强大的平台不是一朝一夕建成的,我们制定了自如DevOps体系的路径规划,大体分为3个阶段,如图3-5所示。
图3-5 阶段发展图
1.0阶段:打基础,提升研发工程师和运维工程师的专业技能,修炼内功。
前面我们分析了能力差距,要想提高研发生产力,最重要的是提升人员能力,这是打造DevOps体系的第一步。只有研发人员熟悉运维知识,知道常用的服务器如何操作、出了线上问题可以快速识别是内存问题还是I/O问题,才能更加高效地发布与部署、定位问题、解决问题。同样,只有运维人员掌握了一定的开发知识,才能够从繁杂的日常事务中解放出来,去研发一些提效的工具和平台。
2.0阶段:优平台,模仿业界一流的平台,提升研发工具的易用性。
当运维人员转型SRE,研发人员转型DevOps后,人员能力有了一定的提升,我们需要开始分析研发过程的“飞轮阻碍点”——哪个环节、哪个流程、哪个工具在阻碍研发过程的高效流转。是环境的问题吗?是代码分支的问题吗?是提测环节不清晰吗?是发布审批太冗长吗?类似的问题我们要深问,在挖掘到整个研发生命周期的“减速点”“卡顿点”后,下一步通过改造平台来解决问题。
3.0阶段:赋能力,为研发、运维、测试工程师赋能,打造DevOps文化。
“酒香也怕巷子深”,有了工具,就要为广大工程师赋能,让全生命周期的角色都参与起来,用好工具。能够通过大盘看报表就不要用Excel;能够通过平台做一键代码分支合并,就不要用GitLab的命令手动合并;能够一键链路追踪,就不要人工查日志、写脚本过滤。