《软件研发效能提升之美01》

内容来自《软件研发效能提升之美》一书 上一节偏思想方面,这次更多偏实操相关 DevOps落地精要 核心解读 DevOps字面上是Development和Operations的组合,即开发、运维⼀体化,测试作为质量保障角色也会融合其中,⼀体化最大的优势就是打破壁垒、拉通职能,最终体现在效能的提升上,同时把握产品质量与业务增长的平衡点 DevOps的六大武器 标准化作业 好处是能够固化流程,将人力从重复劳动中解放出来,同时有效地减少错误的发生 快速失败 DevOps实践中,通常会引入CI/CD技术,通过高频集成和高频交付,将问题暴露在早期 快速反应 消除角色壁垒,尽可能用工具替代人力,并用流水线方式加速流程 高质量与高效率 DevOps通过持续部署、快速反馈的方式,更好地将不确定性逐步转变为确定性,从而保障⾼质量交付 降低成本 当DevOps模式运作成熟,尤其是快速迭代的流水线初成规模后,软件研发的效率将大大提升,研发成本将明显降低,应对变化的能力也将大幅提高 团队协作 DevOps依靠⼯具和自动化(尤其是流程自动化)来弥补开发与运维之间的技能鸿沟和沟通鸿沟,将软件研发中的三大角色(研发、运维、测试)有效地黏合在⼀起 DevOps是⼀种软件研发管理模式和思想,是⼀种文化实践,并不是具体的⼯具或技术,所有在保证质量的前提下提升效能的方法都属于DevOps的范畴 DevOps生命周期 持续开发 持续开发包含计划和编码⼯作,伴随这⼀阶段的工具主要有代码仓库、版本控制⼯具、包管理⼯具,以及⼀些计划可视化方法,如⽢特图、燃尽图等,也会涉及分⽀管理、单元测试等⼯作 持续集成 持续集成是DevOps中最核⼼的组成部分,通过频繁地提交代码、频繁地编译代码、频繁地构建项⽬、频繁地执⾏单元测试等,不断高频集成,贯彻快速失败的原则,尽可能早地收敛问题 持续测试 持续测试需要确保软件代码的每⼀次提交都能够被及时验证,并输出完整的质量反馈。纯⼈⼯的⽅式很难做到持续测试,⾃动化测试和容器化手段是这⼀阶段的标配 持续监控 这⾥的监控不仅是指对软件运行状况的监控,还包括对DevOps各项⼯作执⾏的监控,以便我们及时做出处理和纠正。持续监控还可以提供历史趋势信息,帮助我们更好地提供决策依据 持续反馈 整个软件研发周期的每⼀项⼯作都对外暴露了大量的信息,持续反馈在每个关键节点介入,以各种形式总结输出反馈建议,并不断改进,从而推动项目良性循环 持续部署 持续部署同样基于高频的理念,尽可能早地让软件产品接受生产的检验,快速发现并收敛问题,保证软件产品及早与用户见面 持续运营 运营阶段涉及对事件和变更的管理,如配置管理、容量管理、高可用管理、用户体验管理等,是DevOps的最后⼀个阶段。运营也是⼀项连续性的⼯作,是需要持续不断进行的。相对于其他周期项,持续运营更需要具备全局视角,才能做到目无全牛 不适合DevOps的场景 在⼀些传统行业或政府机关,软件需求较为固定,甚至会采用外包的方式,且研发周期较长,对质量要求很高 传统金融领域或⼀些从事机密行业的商业机构 代码,分支与流水线 代码是软件产品的原始生产产物,经过编译、构建、测试、发布、部署后,形成可用的产品对象 三个重要因素对研发效能起关键作用 代码,软件产品究其本质都是由代码构成的,代码的质量直接决定了整个研发周期的投入和产出 分支,我们探讨的不是小作坊式的单⼈开发模式,软件开发团队需要在同⼀代码基础上并发进行多个功能的代码编写活动,显然不可能让员工在相同文件上作业,这时候就需要分支和配套的⼯作流。分⽀的实质是能够让研发活动并发起来,提升效率 流水线,在上述例子中,无论是软件代码的集成和交付过程,还是厨师生产美味佳肴的过程,都是⼀道道⼯序不断向前推进的 持续过程。流水线⼀方面可以使流程固化,避免⼈为因素造成的不确定性;另⼀方面能够透明地将每道⼯序的结果呈现出来,便于及早识别问题 代码质量 代码质量不是研发单体的责任,发现质量问题也不是测试单体的责任。我们所谈到的代码质量是需要由软件项⽬中涉 及的所有角色共同保证的,⽬的就是尽可能早地将质量问题消除在源头。绝⼤部分缺陷都是在编码阶段“写”出来的,⽽问题发现得越早,修复的成本就越低 测试驱动开发 从实践⾓度来讲,狭义的TDD,即UTDD(Unit Test DrivenDevelopment,单元测试驱动开发)对研发模式的侵⼊性是⽐较⼤的,现实中很多研发⼈员会不习惯,导致推⼴困难。我们可以考虑将测试⼯作上升至业务层,推行ATDD(Acceptance Test DrivenDevelopment,验收测试驱动开发),先定义质量标准和验收细则,再通过⾃动化测试的⽅式进行验收,这样就能够在代码编写和交付阶段预防缺陷 静态扫描 ⼀种成本较低的质量保障手段,它最⼤的好处是不需要运行代码,仅仅通过分析静态代码结构和抽象语法树,就能发现潜 在的风险和违反规约的地方。目前市面上比较流行的静态扫描⼯具有阿里的代码规约扫描⼯具、Sonar、Findbugs、PMD等 代码评审 代码评审对质量保障的重要性不言而喻,但实际⼯作中就是另⼀番景象了,做得好的团队经常能够主动发现代码问题,做得不好的团队则流于形式,草草签字、画押了事 并至主干分支前进行,评审完成后再进行正式的测试⼯作 分支与工作流 分⽀的存在允许多人同时⼯作而互不干扰,不过我们总要在某个时机,将多分⽀代码合并成⼀份,以便⽣成最终交付的代码版本,这个过程涉及版本管理、发布管理、缺陷修复等⼀系列环节 工作流: Git Flow⼀共设计了5种分支,其中包含两种长期存在的“主要分支”(master和develop)和三种暂时存在的“协助分 支”(feature、release和hotfix) master分支上保持的版本必须是时刻可以发布运行的,因此不允许在master上直接进行修改和提交,只有其他分支的代码经过⼀系列的流程验证后,才能合⼊master。 develop分支是代码开发的基准分支,也不允许直接修改和提交。 feature分⽀是开发者编码的主要⼯作分支,在develop分支建⽴完成后,通过PR的⽅式合并回develop分支。 release分⽀是⽤来进⾏版本发布的分支,发布成功后分别合⼊develop和master分⽀。 hotfix分⽀⽤于处理紧急bug修复,在master分支建⽴、修复完成后,hotfix分支将合⼊develop和master分支 流水线 从DevOps的视⾓看,流⽔线是持续交付的载体,通过构建⾃动化、集成⾃动化、验证⾃动化、部署⾃动化等⼯作,完成从开发到上线的持续交付过程。其中,每个环节相当于CPU中的各个电路单元,在整体上形成了并⾏的效果,通过持续向团队提供及时的反馈,让交付过程⾼效、顺畅 精益理论强调了价值流动的重要性,⽽价值流动需要通过⼀定的⽅式来体现,DevOps流⽔线从某种程度上说就是⼀个很好的 载体,因为它⼏乎覆盖了整个端到端的流程。在流⽔线上,各环节流转得越快,价值流动就越快,这间接体现了公司的研发效能 Jenkins Pipeline⽀持声明式和脚本式两种脚本编写⽅式,前者语法限制多,偏模板化,⽽后者则更⾃由,善于应对复杂的需求。下⾯我们以声明式的⽅式尝试编写⼀个流⽔线脚本,覆盖代码拉取、构建、部署、测试等⼀系列环节 持续集成与持续交付 集成,指部分向整体合并的过程,⽐如,某⼯程师研发的代码,将其合并到主干的过程就是集成,这其中涉及编译、打包、构建、单 元测试等工作。...

《软件研发效能提升之美00》

内容《软件研发效能提升之美》之书 总论 研发效能是多⼈组织协同效率的课题,在现代基础设施、架构理论和AI算法的加持下,研发效能的内容也从敏捷方法论快速进化到非常具体的⼯具、流程和指标系统 研发效能定义:在保证质量的前提下,尽可能⾼效地持续交付价值。为此,我们重新审视 整个软件⽣产流程(需求、设计、开发、测试、部署、发布、运营),在不增加成本和保证质量的前提下,提升各个步骤的标准化、⾃动化、系统化和⼀致性⽔平,并不断优化团队的交付效率 **没有银弹:**没有任何一项技术或方法可使软件工程的生产力在十年内提高十倍 希望软件研发能够成为⼀个技术密集型产业,⽽不是劳动密集型产业 敏捷作为⼀种通过创造变化和响应变化在不确定和混乱的环境中取得成功的能力,具备高度的实践性和创造性,这样的特性在赋予敏捷强大适配度的同时,也给落地造成了困难 概述 研发效能提升案例 前端代码的自动生成 我们手绘出GUI界⾯的草稿;通过Sketch2Code可以直接将这份草稿转换成目标平台的代码,如果我们指定的目标平台是Web,那么代码格式就是HTML,如果我们指定的目标平台是iOS,那么代码就以XCode项目的形式呈现;最后,完成编译打包,可直接在iPhone上安装执⾏了。 这种方式的引入将大幅提升原型构建环节的效率 临界参数下的API测试 考虑引⼊⼀种机制,通过⼯具或脚本去主动检测API输入参数的类型,根据不同的类型⽣成相应的容易出错的临界值,我们⽤这些临界值作为测试数据去⾃动调⽤API。如果API返回预期外的异常或错误(如HTTP-500错误),那就说明这个API没有妥善处理我们传⼊的临界值 进⼀步的,我们可以将这个机制与CI流水线集成,在CI执行走过程中主动执⾏临界参数下的API测试,以求问题更早地被暴露 例如:当⼯具或脚本识别到某API的输⼊参数是String类型的时候,就可以⽣成NULL、超⻓的字符串、包含⾮英语字符的字符串、SQL注⼊字符串等⼀系列临界值,将其作为测试数据去检测程序潜在的问题 基于流程优化的效能提升 效率的提升既可以由技术来驱动,也可以由流程来驱动,流程要整体方便 第一性原理:顺畅、高质量地持续交付有效价值的闭环 顺畅:价值的流动过程必须顺畅,没有阻碍 高质量:如果质量不行,那么流动越快,死得也会越快 **持续:**不能时断时续,小步快跑才是正道 **有效价值:**这是从需求层⾯来说的,你的交付物是不是真正解决了用户的本质问题 **闭环:**强调快速反馈的重要性 鹅生金蛋的故事。是不是鹅生的金蛋越多,效能就越高呢?其实不是,⼀味地让 鹅全日无休地生金蛋,早晚会把鹅累死,这不是可持续的长远战略。真正的效能应该是让鹅生鹅,鹅再生鹅,让更多的鹅⼀起来下金蛋 从软件开发、测试和发布的视角来看⼀下各个阶段研发效能提升需要关注的问题,其主线是围绕CI/CD的⼀些实践 举例:选择合适的发布策略也会对效能和风险之间的平衡起到积极的作⽤ 架构相对简单,但是集群规模庞大,则优选金丝雀 架构⽐较复杂,但是集群规模不是太大,可能蓝绿发布更占优势 研发效能这个领域,要保证我们所做的研发效能工具⼀定是能解决实际问题的 研发效能提升实践: 找钉子,场景举例: 本地编译耗时长:提供增量编译和分布式编译能力 本地测试困难,测试环境准备复杂且耗时长:基于Kubernetes的Pod提供⼀键搭建测试环境的能力 自动化测试用例数量大,执行回归时间过长:采用并发测试用例执行机制,使用几百、几千台测试执行机并行执行用例,实现用硬件资源换时间 自动化测试用例维护成本高:测试用例采用模块化和分层体系,实现低成本的自动化用例维护 测试数据准备困难:引入统⼀的测试数据服务(Test DataService)能力 集群规模庞大,发布过程耗时过长:各个层级的并发部署能力,集群内节点的并发、集群间的并发等。 项目的过程数据都是后期集中填充,失去度量意义:项目的过程数据由⼯具自动填充,不再依赖⼯程师手工输入。比如,开发完成的时间不再依赖于开发人员手工填写,而是由Jenkins构建完成后自动填写,以保证所有过程数据的真实有效性,从⽽为后面的度量和改进提供可靠的信息输入 全局切入: 软件缺陷的流转,软件需求的实现与交付,软件制品包发布等待 持续改进: 比如,需要在Jenkins中通过hook机制去触发⼀些操作(比如代码静态扫描、单元测试等),最简单的做法就是在hook中实现操作的具体步骤,这种实现在开始时效率很高,也非常容易实现,但却不是最优的⽅案,因为hook中的代码只会被执行⼀次,而且hook越来越多以后,各种实现都散落在各个地方,难以维护,⼀旦有新的需要(比如要加⼊慢SQL扫描),就需要改hook实现,而且这种做法也违背了IaC(Infrastructure as Code)原则。 更好的做法是引入研发效能的消息中心,通过下游操作的订阅模式来实现未来的可扩展性 效能平台的灵活性 将Jenkins持续集成⼯具视为⼀个平台,在这个平台上支持安装各种插件,以增强平台功能,从而实现平台架构的灵活性 杜绝"掩耳盗铃" 代码质量门禁Sonar设而不卡 单元测试只是执行,不写断⾔Assert 代码覆盖率形同虚设 Peer Review走过场 代码递交过于随意 监控超配,有报警但无人认领 发展方向与未来展望 研发各个环节的全链路横向打通 CI/CD和测试不再是⼀个个独立的环节,软件研发从需求开始到最终线上交付采用⼀站式的研发效能平台,实现统⼀的研发⼯具和流程 研发全流程的可视化 研发流程的可视化在后期⼀定会成为⾏业的标配,通过流程的可视化,可以展示各个需求的进展情况,让各级管理者和⼀线⼯程师清楚地知道项目目前所处的状态。 “稳态”和“敏态”齐头并进 研发效能的提升并不⼀定都要绑定到敏捷开发实践上,事实上,对于那些需求明确并且稳定的项目,传统的瀑布模型依然是最佳的选择,此时采用“稳态”实践才是获得最佳效率的途径。只有那些需求变更频繁的项目才是践行敏捷实践的最佳选择。因此,敏捷对传统瀑布而言并不是取代,⽽是互补,“稳态”和“敏态”会在长时期内和谐共存。 研发能力的中台化沉淀 研发各阶段的垂直能⼒必然会沉淀到中台,以统⼀服务化的形式对外提供服务。⽐如,代码覆盖率的统计能⼒会统⼀到⼀个单⼀的服务中,为各个语⾔的业务提供代码覆盖率的统计;再如,分布式编译加速的能⼒也会成为企业级的服务,为各种⼤型项目提供编译加速。 数据驱动下的效能提升 以后的决策⼀定会基于数据来开展。效能提升实践的效果衡量也会⾼度依赖于数据。研发效能数据中台的建设必定会被提上⽇程,通过收集存储研发各阶段的各种过程数据,实现基于研发效能⼤数据平台的决策体系 进阶解读 软件生产作为智⼒密集型活动,掺杂着⼤量人的因素,很难严格地标准化 质量和效能是“既要、也要”的关系,效能的提升能够将软件研发中的⻛险更快、更及时地暴露出来,同时减轻⼈脑负担,反过来⼜ 能提升质量本身 渴望尊重和欣赏,是⼈性的需求之⼀。适度的关注和赞美能够产⽣强烈的心理暗示,继而带来效能的提升 反摩尔定律告诉我们,越迟交付的价值其价值越低 信息熵衰减对研发效能的影响是巨⼤的,要想方设法将信息传递的效率提升上去 自解释的代码不是无注释和无文档的代码,而是伴随着⾼信息熵的代码体系。内容简洁合理的注释与⽂档,同样也是优秀代码的⼀部分,能够给效能的提升带来帮助 基于流程优化,打破各个环节看不见的墙,去除不必要的等待,提升价值流动速度,这些是研发效能试图解决的一大类问题 项目管理提效 敏捷宣言...