cover_image

收钱吧研发效能实践之工具篇

刘宁 SQB Blog
2022年08月24日 06:01

编辑 | 邵一帆,徐豪

图片

前言

在降本增效火起来之前,每个研发团队就已经对效能二字充满了非比寻常的热忱与执着。究其原因,就在于研发工作经常会给人带来巨大的困扰。其一,每次代码提交后,研发人员都需要进行构建、测试、部署、合并等大量重复性的工作,当项目临近发布日期时,便倍感压力;其二,依赖手工的配置管理难免会在这种重复性的工作中出现人为错误;其三,在产品交付过程中,由于必要又不太熟悉的工具、看不懂的各种报错、搜不到的解决方法等技术上的壁垒存在,同样耗费研发人员大量的时间精力。怎样减少研发人员的时间不被无谓的浪费,如何将人的效率最大化激发利用,从而释放研发人员的创造性和积极性,是每个研发团队都会耗费心力去思考的事情。

关于研发效能的理论、体系、指标、框架方面的文章,近年来在网上层出不穷,其中也不乏有一些大牛的理论分析与实践建议,如,InfoQ[1]上有一整个专题讨论研发效能。我们在此对理论和管理上的分析和设计不做赘述,仅简单介绍收钱吧在工程和工具层面所做的实践和改进。

CI/CD

研发效能工具链的提升,首当其冲离不开CI/CD。

图片

CI全称Continuous Integration,意思是持续集成,指在开发过程中,经常性地提交代码与之前的代码进行集成,每次集成都经过一些自动化过程进行验证,如自动构建、自动测试、自动部署等,这样就可以提高代码开发和集成的效率,并且可以尽可能早的发现集成过程中的问题。

CD通常指Continuous Delivery,意思是持续交付,它建立在持续集成的基础上,对软件产品进行发布和部署。现在,CI/CD通常一起使用,来指代提交代码到上线发布过程中的一系列自动化流程。

CI/CD的建设水平,直接关系研发团队的生产效率和产品的交付周期。理想情况下,从提交代码到上线发布都通过自动化流程实现,无需人工介入,而现实情况中上线发布难免会受到一些人工的干预,有时候是因为技术的原因,有时候是因为业务的原因。在这样的情况下,我们介绍下收钱吧在建设CI/CD流程中遇到的问题以及对应的解决方案。

CI/CD流程优化

2018年之前,收钱吧使用Jenkins作为CI/CD的解决方案。Jenkins是一款开源CI/CD软件,用于监控持续重复的工作,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。Jenkins扩展性较好,插件的拓展可以大大提升研发效率和规范产品开发流程。

图片

使用Jenkins,可以很容易配置出CI/CD的流水线。但是随着业务的发展,Jenkins的弊端也逐渐显现出来。

  • 公司大多数项目是直接通过Jenkins界面配置项目的Pipeline Script,在发布过程中,由于项目的CI流程如出一辙,造成了大量重复配置,加剧了系统开销,也增加了维护难度
  • 由于在界面配置Pipeline,开发者无法对脚本进行版本管理,便导致了同一项目代码的不同分支无法执行不同的CI流程
  • Jenkins本身需要一定的维护成本,管理密钥、插件,安装agent,开发共享库等

在2018年,公司将所有服务从Docker部署迁移到K8S集群部署,原来Jenkins上的使用Docker部署的CI流程不再适用。由于逐个修改Pipeline脚本工程浩大,再加上,公司代码原本就托管在的Gitlab上,所以考虑到将CI流程迁移到Gitlab内置的CI上。

图片

相比于Jenkins,Gitlab CI具有很多先天的优势:

  • Gitlab自身就是版本管理工具,CI配置文件先天就具有版本控制
  • 本身作为代码仓库,无需在拉取代码上做权限控制,开发人员的Gitlab用户权限就是CI流程对代码仓库拥有的权限
  • CI的执行日志就集成在Gitlab上,查看日志的方便度大大提高,并且,日志可以清晰地显示代码分支和提交时间
  • 可以方便地在不同项目之间触发关联的构建

除了这些先天优势,Gitlab CI的配置文件也非常简单,几乎没有学习成本,而且模版文件的创建和引用,相比于Jenkins来说也要简单许多。Gitlab还支持多种执行器,适应不同的使用场景。我们目前使用K8S执行器。当任务规模达到一定量后,K8S几乎是一个必然的选择,相较于其他执行器,它有以下优势:

  • 安装简单,使用Helm一键安装,而且自动注册
  • 通过提供统一的基础镜像,任务可以运行在我们提供的纯净环境中,避免环境污染
  • 无需关注任务的资源调度问题,资源分配由K8S集群处理,资源可以做到弹性伸缩,节省费用

收钱吧使用Gitlab CI的实施方案:图片

  • 组件化配置:创建了统一的CI配置仓库,每种类型的任务可以定义成单独的模版文件
  • 自由组装:业务项目引用仓库配置,最终的执行流程,由多个模版文件合并后的结果决定
  • 任务管理:CI/CD任务由Gitlab进行管理,包括任务生命周期管理、日志收集
  • 资源管理:资源调度由K8S集群管理

代码分支自动化

CI/CD进行的是代码提交到部署之间的自动化,而我们在不断优化CI/CD流程的基础上,又将自动化向前进行了延伸,在代码提交之前,也进行了自动化。

在大多数软件公司中,需求管理和代码开发之间常常是断开的,或者即使有关联也是人工进行关联,代码分支也由开发人员手动管理,这样就会造成以下问题:

  • 代码分支管理混乱:分支名称、tag标注如若没有人为规范,服务扩展性便会下降,技术管理的复杂性也会提升
  • 代码和需求之间关联困难:当需求增加、一人多需求并行开发、单需求多人协作,可能会造成代码提交错分支、返工,降低开发效率

收钱吧目前使用Jira做项目管理,依托Jira的插件和工作流能力,开发了分支代码自动化。

图片
  • 一个Jira主任务下可以创建多个子任务,子任务创建时,可以选择对应的Gitlab项目
  • 子任务进入开发流程时,系统自动会创建对应的release分支和feature分支,开发人员将对应分支pull到本地即可进行开发
  • 子任务提交审查后,会自动创建Merge Request,代码审查通过后合并入release分支
  • 测试人员使用release分支进行测试,测试通过后合入主分支,系统自动打上tag

这只是一个简化的模型,实际应用过程中,可以根据Jira的不同的任务类型,决定代码分支的管理模型。统一的分支管理、任务和分支的双向关联,可以让开发人员的认知保持一致,使个人的多任务开发的分支管理不再混乱,使多人协同开发、跨团队之间的合作,减少了很多不必要的沟通成本。

制品管理优化

说到CI/CD,就不能不说制品管理。制品是在CI/CD过程中产生的各种软件产品,如jar包、npm包、Docker镜像等等。这些制品会被其他的项目依赖或者被其他的CI流程使用,需要进行管理,能够方便地存储和查询,同时要对不同的制品进行权限管理。

在优化之前,制品关联存在以下乱象:

  • 各种编程语言的制品分散在各个仓库,没有统一管理
  • 制品仓库没有权限管理,开发本地、CI流程中都可以任意上传,甚至覆盖,造成依赖关系混乱
  • 开发、预发布、生产等各个阶段的制品混杂在一起,无法识别制品的有效性和稳定性
  • 制品的各种规范,如命名、版本管理,没有强制的流程来保证

交付的软件都是在这些制品上构建起来的,如果制品是一团混乱,那最终交付的软件的可靠性也需要打一个问号。所以我们为了完成以下目标,重新设计了制品管理流程:

  • 统一的制品仓库
  • 分仓库存储不同阶段制品
  • 制品经过验证后晋级
  • 区分各阶段仓库读写权限

在制品管理改造的方案上,收钱吧选择了JFrog,对所有制品进行统一管理。同时在JFrog的基础上,结合自身的研发流程特性,设计了制品的上传和晋级逻辑。

制品上传逻辑:

图片
  • 仓库隔离:不稳定制品的dev仓库和相对稳定的staging仓库隔离,制品解析时互不干扰。
  • CI/CD Runner隔离:dev runner和staging runner的环境配置隔离,不同的runner拥有不同仓库权限
  • 上传权限:本地调试和开发阶段CI的制品,只能上传dev仓库;只有预发布阶段的runner可以上传制品到staging仓库;prod仓库的制品无法上传,只能从staging仓库中晋级

制品晋级逻辑:

图片
  • 镜像交付:生产环境部署的镜像,和预发布过程中验证的镜像,只能是同一个镜像。记录镜像中使用的制品以及制品的依赖。
  • 合规验证:测试完成之后,在预发布阶段进行镜像合规验证,验证通过之后,镜像晋级,可以在生产部署
  • 制品晋级:镜像上线验证通过后,镜像对应的制品及其依赖晋级到生产,供其他项目依赖使用

通过仓库隔离和权限控制,既保证开发测试环境的灵活方便,又保证预发布和生产环境安全稳定。在CI流程中,还可以增加一些个性化的控制,如可以控制制品的覆盖逻辑、上传各个仓库制品需要满足的命名规范等。

SCA

在建立起规范的制品管理流程的基础上,CI/CD流程中便可以加入软件成分分析(SCA[2])。SCA是分析软件组件成分的一套方法论,它要求我们重视我们的应用程序代码中依赖的组件成分。

为什么SCA如此重要?根据Snyk Vulnerability DB[3]披露的漏洞数据来看,开源软件每年新增的漏洞数基本都在逐年增加。

图片

如今,绝大多数应用程序的代码都会依赖大量的开源组件,只对自研部分代码进行静态扫描、单元测试等动作是不够的。这些开源组件中可能会包含严重的漏洞,包括近期著名的log4j漏洞。如何识别这种潜在的威胁,成了软件开发中的挑战。SCA主要具有以下挑战:

  • 代码的低可见性:应用程序中依赖组件,组件中又依赖其他组件,层层的依赖,使得应用程序很难弄清楚到底使用了开源组件中的哪些代码
  • 依赖逻辑:层层的依赖过于复杂,我们需要工具来支持组件的逻辑依赖关系
  • 漏洞数据库:关于组件漏洞的数据分布在各种数据源里面,漏洞和被影响的组件匹配也比较困难,有些数据源存在漏洞数据滞后的问题

比较成熟的SCA解决方案有:

  • 商业版解决方案:JFrog Xray、WhiteSource、Snyk等,商业版的最大缺点就是价格昂贵,每年至少需要多花费10多万元
  • 开源解决方案:DependencyCheck,有Jenkins和SonarQube插件,但是测试下来有比较多的漏报误报,而且依赖的NVD数据更新不是特别及时

但是不管是开源的方案,还是商业版的方案,都只是用来分析软件依赖中的存在高危漏洞的开源组件成分,对于公司内部自研的组件,如果存在业务需求需要强制将对应组件废弃,那以上方案都无法满足。基于上述原因,收钱吧自研了SCA分析,并将分析结果与发布流程结合:图片

  • CI依赖解析:在CI构建过程中,将应用程序的依赖关系上传Next平台,Next平台分析依赖树,结合漏洞数据库,生成高危组件报表,同时给黑白名单决策提供依据
  • 上线流程控制:命中黑白名单的组件,包括开源组件和公司自研组件,依赖这些组件的应用、docker镜像,Next平台都会拦截它们的上线发布,SCA流程的完善,将对应用程序的安全性提供一定保障

系统上线之后,截至目前共分析出469个应用中共206个不同的高危组件,且提供完整的报告和修复建议。

图片
图片

同时,在应用部署过程中进行拦截。

图片
图片

Next平台

CI/CD中提到的几种优化方法,仅仅只是一些支离破碎的点和线,所有这些点和线,都由收钱吧内部系统Next平台编织成面。在《收钱吧多泳道环境的演进》[4]一文中简单提到过Next平台。Next平台定位为一站式研发流程管理平台,目前它的主要功能有:

  • 项目管理:跟踪项目管理过程中的各个阶段,记录项目进度,管控上线发布,管理项目成员,自动化项目过程中的文书工作
  • 应用管理和部署:管理收钱吧的应用程序,提供将它们部署到K8S集群的能力,提供多泳道环境支持
  • 制品管理:查看和搜索制品,漏洞组件数据库,应用漏洞组件数据统计
  • 团队报表:各团队项目用时统计信息,各项目阶段耗时甘特图,项目bug统计信息等

常见的软件交付流程中,大致都会经历开发、测试、预发布、上线等阶段,虽然每个阶段内有CI的支持,但是阶段之间的转换常常需要人工进行确认,可能包含会议或者邮件等形式。在Next平台上,项目流程管理是核心功能,其他功能都围绕它进行展开。项目各个阶段中产生的技术指标,可以成为进入下一阶段的评估条件,在阶段的转换中,逐渐弱化人工确认,强化使用技术指标作为阶段转换的条件。这样,可以使得CI中各项指标为研发流程所用,研发流程可以最大化地实现自动化、标准化,从而提升研发效率。

虽然Next平台目前支持的功能还比较有限,但未来将有越来越多在研发流程中需要用到的功能通过插件的形式集成进来,从而提供更多的技术指标,建立起越来越完善的研发交付流程。

图片

总结

随着收钱吧业务日益复杂,为了帮助研发团队提高生产效率、缩短产品的交付周期,我们对CI/CD做了以上优化。在CI/CD流程的优化使得同样多的硬件资源可以支持更多的任务,并且因为CI任务时间分布明显的峰谷特点,依托k8s集群的资源调度加上节点弹性伸缩,并且硬件成本也进一步压缩,节省开支。针对技术管理的痛点,代码分支自动化和制品管理的优化帮助研发人员更加高效地专注于业务需求,无需处理琐碎的技术细节,提高生产效率。我们自研的SCA解决方案,在一个季度内也完成开发和推动落地工作,不但具有商业解决方案(至少10万元/年)的功能,而且能够融入原有的项目交付流程,降低交付项目中存在的安全隐患。未来,关于Next项目方面的工作,我们将持续扩展工具链,将工具插件化,丰富Next平台生态,同时充分利用工具输出的结果,完善指标体系,让项目交付规范化、标准化。

关于作者

刘宁,来自技术平台部

参考资料

[1]

研发效能启示录: https://www.infoq.cn/theme/107

[2]

Guide to Software Composition Analysis (SCA): https://snyk.io/series/open-source-security/software-composition-analysis-sca/

[3]

Open Source Vulnerability Database: https://security.snyk.io/

[4]

《收钱吧多泳道环境的演进》: https://mp.weixin.qq.com/s/8DlQ4Q6lqACn4WUMjsPzgw

图片


继续滑动看下一个
SQB Blog
向上滑动看下一个