编者按:本文源自阿里云云效团队出品的《阿里巴巴DevOps实践指南》,扫描上方二维码或前往:https://developer.aliyun.com/topic/devops,下载完整版电子书,了解阿里十年DevOps实践经验。
构建是将源码变成制品的过程。构建包括编译,但不等同于编译。即使对于不需要编译的解释型语言,也要构建成一个压缩包或 Docker 镜像再去部署。无论是在开发阶段还是 CICD 阶段,都离不开构建过程,构建的质量和效率对持续交付影响很大。影响构建效率的因素,包括源码以及构建的依赖。
背景
在阿里巴巴,Java 是被最多人使用的编程语言。在 Java 的构建工具中,由于迁移成本,生态等原因,Maven 一直是服务端应用的最主要构建工具。
Maven 构建性能问题主要有二方面原因。一是外因,从应用角度看,一些 Java 应用历史悠久,依赖不断增加,并因为清理有风险导致累积太多,典型应用有 3000 个 Jar 包依赖,而且这些应用研发人员多,且是跨团队的,导致依赖管理成本高,依赖变得复杂混乱。二是内因,从 Maven 本身来看,它对复杂依赖的处理考虑欠妥。
对于外因,需要业务团队建立依赖梳理管理机制。针对内因,我们对 Maven 进行了重新实现,推出了 AMaven。
另一方面,阿里巴巴有 15%的 C/C++应用。C/C++应用与 Java 的最大区别是:Java 应用构建次数频繁,但每次构建时间短;C/C++应用构建次数少,但一次构建时间长。如某些软件的构建长达 10 多个小时。所以C/C++开发同学的痛点,除了构建慢外,最不能忍受的还是等了 10 多个小时,最后几分钟居然构建失败了。
那为什么 C/C++构建慢且容易失败呢?
原因主要有两个:
- 现有框架无法保证 C/C++编译和链接的严谨性,导致编译结果不确定,运行时也不稳定。举个例子,在编译阶段,同名的头文件在不同时间或不同机器上会可能内容不同,所以编译容易失败。
- 公司内编译框架众多,有 scons,cmake 等,造成团队之间业务转接成本高,编译问题排查成本高。从平台角度看,也无法触达用户真正的编译逻辑,无法统一性能调优,更进一步无法统一升级底层编译器 gcc,即无法享受新技术红利。所以构建慢。
相比 AMaven 是重新实现底层构建工具的 Maven,在 C/C++领域我们主要是建设上层的编译框架,推出了 Alimake,因为底层的 make 已经很优秀了。
接下来,我们具体来看看 AMaven 和 Alimake。
方案
AMaven
Maven 构建带来的性能问题,会严重影响持续交付的效率。主要体现在以下几点:
- 在 idea 中同步时间长,如典型应用需要 10 分钟左右。
- 单次编译时间长,如典型应用也需要 10 分钟左右。
- 构建步骤多,在一次交付过程中,不同环境都要构建。
- 在同一环境中往往会构建多次。
同时,构建性能问题也影响了开发同学的成就感。只写了几行代码,但一刷新工程,一本地编译,就一个上午过去了。一天下来,写代码的时间没等编译的时间多。
构建问题影响软件交付效率
一线研发同学,他的研发工作远不止体现在研发协同平台上的操作,在一个分支能进入集成前,有大部分研发工作都是在线下本地完成的。所以线下本地的提效也很重要。从新的 Java 构建工具 AMaven 开始,我们也将提效的视角范围从线上研发协同平台延伸到了一线研发本地。
基于 Maven 协议,遵循缓存,增量等思想,重新实现了一个工具:AMaven。同时在使用 AMaven 过程中,为保证它构建结果的准确性,在后台也会使用 Apache Maven 进行构建,并比较二者编译结果。同时又是基于 Maven 协议,对用户透明 ,从而做到"无成本,无风险"。
无成本,无风险
结果对比,保证无风险
AMaven 对症下药,主要通过建立依赖树,缓存依赖树,共享依赖树来解决依赖复杂问题。一个依赖树缓存是否有效,除了与源码中的 pom 文件有关,还与依赖的 snapshot 变化等有关。当 snapshot 变化时,依赖树缓存就会失效,而需要重新生成依赖树。为提高依赖树的生成效率,AMaven 还通过依赖遍历算法对依赖树生成进行了优化,并开放了遍历深度参数让用户来微调。
这些依赖树信息同时也会保存为制品的重要元数据,在"制品元数据"章节中会有详述。
依赖缓存与共享
除了利用缓存,增量等思想,AMaven 还做了 C/S 化。即将部分计算能力移到 server 端。使用 AMaven后,一次构建的流程变成如下图所示:
一次典型的 AMaven 构建
AMaven 还增加了循环依赖检测,动态执行插件等能力,虽不能直接提升构建速度,但加快了研发同学对依赖等构建问题的排查速度。
我们再来看看 AMaven 给用户带来的收益与效果。从线上 CICD 平台数据来看:AMaven 实现了 Java秒级构建,阿里巴巴的 Java 构建中有 44%在 30 秒内完成。其次,从依赖庞大的典型应用来看,提效可达 10 倍。
从线下研发本地数据来看:AMaven 无论是在命令行还是在 IDEA 中使用,都能将构建耗时降至 50%。特别是在 IDEA 中切换分支后刷新工程时,最快能在 10 秒内完成。
Alimake
Alimake 主要从两方面入手。
- 从"规范"入手。首先,建立全新的严格的配置文件 target,所有编译入参必须严格清晰的定义,它会被翻译成严谨的 makefile,它也同时在一定程度上培养了工程师严谨自律的文化。接着,建立了一个全新的仓库 alicpp,它统一存放了原本在编译机器上的依赖,从而保证编译的环境无关性,保障编译结果的强一致性。
- 从"效率"入手。它不但集成了业界优秀技术 ccache 和 distcc,而且还自研了分布式链接等技术。因为 Alimake 统一了入口,所以它不但能让专家经验规模化,统一调优编译参数,而且还能将升级编译器 gcc 机制化,让我们可以随心所欲,一直跟上编译器的进步。
Alimake 的架构思想与 AMaven 类似,也是将部分计算能力移到 server 端。利用 server 端一来能减轻client 端的资源消耗,解决 client 端由于硬件及配置带来的性能瓶颈,二来也能实现资源共享,如依赖缓存,中间产物缓存。
Alimake 架构
Alimake 覆盖阿里巴巴多个产品,包括:钉钉、阿里云存储、OSS、盘古、伏羲、蚂蚁人工智能等,平均提升构建效率 30%,最优情况下可以提效 70%。
小结
为提高构建效率,我们从空间(产物大小),及时间(通过工具来提升构建速度)二方面进行了优化。除此之外,还利用构建过程中产生的原生数据(如依赖关系),赋能于持续交付与安全生产等方面,以实现高效的可信的发布。
免费下载《阿里巴巴DevOps实践指南》
阿里巴巴合伙人和业界多位大佬力荐、何勉、陈鑫等17位阿里资深技术专家联袂出品、阿里十年DevOps经验沉淀总结、阿里巴巴DevOps落地实践一本通。
前往:https://developer.aliyun.com/topic/devops,下载完整版电子书。