ZBJ DevOps 平台的 CI/CD 流水线实践:提高研发效率与交付质量

2024-06-03
来源:网络整理

本文旨在介绍ZBJ团队打造的平台中CI/CD流水线的实践,历经三次大版本迭代的流水线完美满足了ZBJ各项业务发展需求,在满足高频次交付的同时,提升了研发效率,降低了研发成本,保证了交付质量。

持续集成( ,简称CI)。持续集成强调开发人员提交新代码后,应立即进行构建和(单元)测试。根据结果判断新代码和原有代码是否可以正确集成在一起。在持续集成过程中,我们非常重视自动化测试验证的结果,并对一些可能出现的问题进行预警,确保最终集成的代码不出现问题。

持续交付(CD)简称CD,在持续集成的基础上,持续交付将集成后的代码部署到更贴近真实运行环境的“类生产环境”(测试),然后交付给质量团队进行评审,如果评审通过,代码就进入生产阶段。

持续交付并不是说每一次软件变更都要尽快部署到生产环境,而是说任何代码修改都可以随时部署,有人也叫CD(持续部署)。持续部署就是当交付的代码通过评审后,就可以部署到生产环境。这里要注意,持续部署应该是持续交付的最高阶段,持续交付是一种能力,是持续交付的一种体现。

在讲ZBJ管道之前我先解释一下历史背景,2015年之前猪八戒网80%的项目都是用PHP开发的,剩下少部分是用Java开发的。

2015年,ZBJ研发中心进行了一次自发的“产业革命”——腾云7号行动——用Java语言对核心业务代码进行重构拆解,建立以PHP为核心的SOA微服务框架,以+为核心的业务调用提供机制,满足新业务用Java语言编写,而旧业务仍用PHP编写的需求,并支持两种语言(&PHP)的服务调用能力。

在这之后,前后端分离全面推行,流行至今仍在使用的主流架构:

其余的小系统或者边缘工具都是用其他语言开发的,或者基于这三种语言的一些变体:

随着业务的重构分解,原来庞大的系统被拆解成几个独立的小系统,交付变得更加容易。

随着项目项目数量的快速增长,交付也变得更加频繁,传统的一两个月交付一次的开发模式已经远远不能满足交付要求,变革迫在眉睫。

2016年第三季度,感觉到变革在即,ZBJ研发中心在经过充分的准备后,决定挑选部分运维同学和开发同学,组成一个团队,名为“学习组”,以提高研发效率为目标,努力打造ZBJ自己的平台。

ZBJ CI/CD发展历史

第一阶段:2015年之前

2015年之前,在“工业革命”还未开始的时候,猪八戒所谓的流水线已经经历了“大锅饭时代”和“公交车模式”。

大底池时代(图片由球队提供)

巴士模式(图片由团队提供)

可以看出,无论是“大锅饭时代”,还是“公交车模式”,都会面临诸多问题:

第二阶段(2016-2017年):私家车模式

通过“工业革命”的变革,对体系进行重构和拆解,引入项目负责制,每个项目指定一个负责人,对项目的各种权限进行管理和控制,业务范围和边界更加清晰,大大缓解了项目耦合度过高的问题。

解决了项目耦合度高的问题,接下来要解决的是如何让开发团队能够随时独立发布代码的问题。

使用Jira管理研发流程,制定ZBJ需求上线流程:

需求上线流程中每个环节都对应着流水线的各个环境,只有到达某个环节才会被推送到对应的环境,每个环节都会制定相应的进入和退出,确保接下来的每一步都离部署成功更近一步。

推送环境图

针对每个环境设置了不同的执行任务,基本包括Jira状态验证、代码评审(单元测试)、编译构建、上传包到工件库、从工件库拉取包并部署到对应环境。

值得注意的是我们引入了发布,所以我们的管道支持容器和虚拟机的混合发布,虚拟机发布的产物存放在一个叫文件服务器的地方,容器发布的产物推送到仓库。

容器发布&虚拟机搭建及打包图

采用的分支策略是:开发、发布、tags 归档(我们用作源代码管理工具)。在测试环境中,通常是不分分支,测试完后合并,推送到预发布,并为当前版本添加一个标签。在这种情况下,我们的“ once, use ”是指测试环境使用测试环境构建的包,其他环境使用预发布构建的包。

产品各环境使用示意图

在推送到各个环境时(测试环境除外),都会验证当前版本的代码是否是之前推送到上一个环境的最新代码,确保没有经过的代码不会交付上线。

在测试环境每次编译构建之前都会对代码进行安全扫描,Java语言项目通过解析pom文件递归扫描其所有依赖,语言项目递归扫描下载的包,确保不会将存在安全漏洞的代码带入生产环境。

在编译构建的时候,会根据开发语言的不同,执行不同的编译脚本,并根据发布方式(虚拟机发布或者容器发布)的不同,执行不同的后续操作步骤。

我们将使用多多架构作为后台编译服务器,没有直接使用,而是开发了一个叫作的系统来与之连接(此时的连接方式是调用API),系统提供了作业所需的所有信息,另外我们编写了整个流程中需要执行特定操作的脚本,并在每次构建之前通过作业配置“ ”将其导入到工作区中。

该流水线标准生产流程如下:

另外,为了应对回滚,上线前的预发布会上会搭建一个稳定版本,并添加一个标签,记录该标签对应的产品(包或镜像)版本。因此,在回滚时,只要选择需要回滚的版本,就可以找到产品对应的版本,重新发布,达到回滚的目的。

回滚过程

小程序开发组建团队需要注意什么_一个开发团队都需要哪些人_组建团队开发app要多少钱

目前为止,二期大致实现了以下功能:

但是这样的流水线也存在很多问题:

第三阶段(2017-2019年):灵活车道私家车模式

考虑到以上两点,ZBJ团队在2017年底对流水线进行了第二次改造:

1、将所有执行步骤分解为独立的原子任务,建立原子任务库;

2、原子任务按功能分为验证和执行两种,验证原子任务主要用于入口和出口判断,执行任务主要用于编译、构建、镜像、上传到hub仓库、部署等。

3、原子任务按照执行载体分为Java类和类两种,Java程序直接执行的任务为Java类,需要执行的任务为类。

4、根据开发语言、发布方式、业务类型,从原子任务库中选择不同的原子任务,形成标准、有序的执行流水线。

5. 为项目提供特殊配置。例如有些项目需要增强验证,有些项目需要减少验证。可以通过启用和禁用来进行特殊配置,如下图所示。经过步骤1、2、3,即可生成本次执行的流水线任务列表。

原子任务列表

执行效果图

6. 根据原子任务的制定,我们还将执行的作业拆分成几个相应的类别,每个类别都有足够数量的作业来执行任务。

7、通过编写插件植入到服务器的方式,对系统及通讯架构进行了升级,将原来的调用API的方式改为使用通讯的方式,大大提高了效率和成功率。

通信图

8、架构升级,构建适配ZBJ所有开发语言的镜像,通过插件的方式将原有的虚拟机节点替换为容器节点,此集群完全由插件调度,无论高并发还是低并发,都可以及时扩容、缩容,满足业务需求。

第四阶段(2020 年至今):智能驾驶模式

可以看到,一直到第三阶段,每一次编译过程都需要研发同事去“推送”,而这个过程也是需要花费一些时间的。比如一个正常项目的平均编译时间至少需要100+s,一个正常Java项目的平均编译时间至少需要30s。由于我们提供推送过程的“可视化”功能,并没有执行结果的通知,因此用户必须时刻关注推送过程,确保推送成功,极大的浪费了研发同事的时间。

在此基础上我们进一步做了以下优化:

1.每个项目添加一个,每次开发者push到仓库都会触发,调用系统接口进行快速构建。

注意:不是每次推送都会触发快速构建,为了防止开发者频繁修改少量代码并提交到仓库,我们指定了一个“秘钥”,只有开发者在仓库中添加这个“秘钥”才会触发快速构建。

代码内容

2.快速构建的结果是构建出一个包或者镜像,存放在上面说的文件服务器或者仓库中。下次用户“推送”的时候,会根据分支和版本判断是否有已经编译好的包或者镜像,如果存在,则直接使用,跳过编译过程。

3.增加快速构建结果通知。由于整个快速构建流程在后台执行,因此管道系统会通过企业微信通知用户本次快速构建的结果。

快速预构建通知

快速构建结果通知

4、除了增加快捷创建通知之外,我们还增加了推送通知功能,用户不再需要关注推送过程,只需在推送结束后继续做其他事情,推送结果会由企业微信通知给用户。

值得注意的是,当推送失败时,管道系统还会通知用户并进行相应的故障排除。

到此为止ZBJ的CI/CD实践基本就介绍完了,当然还有很多细节,不过涉及的东西太多了,不便详细讲。

总结三次大整修的成果

第一次转型:奠定了猪八戒CI/CD的基础,打造了标准化流水线,解放了运维劳动力(流程全自动化),提升了研发效率,降低了研发成本(运维同事从最多的时候三四十人减少到不到10人)。

第二次改造:流水线实现了高可用,并且其灵活的配置可以完美满足不同业务团队的需求。

第三次转型:提升流水线效率,弱化推送流程,增强以人为本的体验,推送流程更加智能化。

谈论未来

分享