【研发效能之道】研发流程优化实践

Posted by 王天一 on 2020-02-18

接下来会以提高用户价值的流动效率为核心,列出一些具体的研发流程优化实践

代码入库前

代码入库之前的开发活动,主要包括编码、调测调优、静态检查、自动化测试、代码审查等。这是开发者编写代码的步骤,自然是提高研发效能的关键环节。

代码集成越晚发现问题就越晚。这正是产品上线的最后关头合并混乱,产品质量差、返工率高的一个重要原因。

规范化、自动化核心步骤

  1. 获取开发环境,包括获取开发机器、配置环境、获取代码等。
  2. 在本地开发机器上进行开发,包括本地的编码、调测、单元测试等。
  3. 代码入库前,把改动提交到检查中心(比如 Gerrit),再进行一轮系统检查,主要包括代码检查、单元测试、代码审查等,通过之后再入库。

对应的有三个实践:

  1. 提高开发环境的获取效率。把整个开发环境的获取,进行服务化、自助化。
  2. 规范化、自动化化本地检查。根据团队实际情况,找到合适的工具和配置进行这些检查,并让团队成员统一使用。
  3. 建设自动化代码入库前的检查流程。比如merge request代码审查、使用 GitLab 提供的 GitLab CI/CD 框架自动化运行各种代码检查工具

提供快速反馈,促进增量开发

提供快速反馈,进行增量开发指的是,能够快速验证已经完成的开发工作,说白了就是边开发边验证。

  1. 灵活使用各种 Linter 和测试。最常用的快速验证方法就是,提高运行静态检查和测试的方便性、灵活性。各种语言、框架都有自己的测试框架和 Linter,根据语言自行设置
  2. 使用实时检验工具。最常见的是,IDE 中的实时语法检查。我们可以花一些时间来配置 IDE。另外,有些工具可以自动监视文件系统的变化,文件有变化时自动重启服务。这对于开发者来说,非常便利。

代码入库到产品上线

三个持续

持续集成:在团队协作中,一天内多次将所有开发人员的代码合并入同一条主干,推荐Trunk Based主干分支模型

  • 它能够帮助开发人员尽量早、尽量频繁地把自己的改动推送到共享的代码仓库分支上,进行代码集成,从而减少大量代码冲突造成的低效能问题
  • 更快地服务客户,以更快的试错速度寻找到用户,提供真正对客户有价值的功能
  • 产品发布到不同环境的过程中,我们会提前发现一些在开发和持续集成中没有暴露的问题

问题:如果有跨多个发布周期开发的功能,有两种处理方式,一是功能开关,但会引进更多逻辑,二是放弃持续集成,那就需要开一个新的功能分支开发(功能分支模型)。所以团队中使用哪种分支模型需要按下图进行判断:

持续交付:一种软件工程方法,在短周期内完成软件产品,以保证软件保持在随时可以发布的状态

目标是,对每一个进入主干分支的代码提交,构建打包成为可以发布的产品。对每一个提交,把集成后的代码部署到“类生产环境”中进行验证。如果代码没有问题,后续可以手动部署到生产环境中。

持续部署:将每一个代码提交,都构建出产品直接部署给用户使用

值得一提的是,跟持续交付一样,Facebook 的持续部署也不是纯粹的持续部署。因为代码提交太多,他们并没有每个提交都单独部署,而是采用类似持续交付的方法,把一段时间之内的提交一起部署。这种不教条的方式,是 Facebook 到的一个重要的做事方法

三个原则

基本原则 1:流水线的测试要尽量完整

CI/CD 流水线的测试只有尽量完整,代码和产品的质量才能有保证。所以,最主要的工程实践,就是在流水线中运行大量高质量的测试和检查。

基本原则 2:流水线的运行速度一定要快

  • 使用并行方式运行各种测试来提速
  • 投入硬件资源,使用水平扩展的方式来提速
  • 使用增量测试的方式进行精准验证。也就是说,只运行跟当前改动最相关的测试,以减少测试用例的运行数量
  • 让开发人员在本地也能运行这些测试,从而使用本地资源尽早发现问题
  • 运行测试的时候,按照一定的顺序运行测试用例。比如可以先运行速度快的用例,以及历史上容易发现问题的用例

基本原则 3:流水线使用的环境,尽量和生产环境一致

  • 软件包最好只构建一次,保证各种不同环境都用同一个包
  • 使用 Docker 镜像的方式,把发布的产品以及环境都打包进去,实现环境的一致性
  • 尽量使用干净的环境。比如,测试时,使用刚从镜像产生的系统;又比如,使用蓝绿部署,每次产生新的部署时,直接丢弃旧的环境。