写点什么

优酷 Android 构建速度优化实践

  • 2021 年 12 月 21 日
  • 本文字数:3991 字

    阅读完需:约 13 分钟

优酷 Android 构建速度优化实践


作者:苏彦郊(木磊)


Android 项目一般使用 gradle 作为构建打包工具,gradle 简洁、动态的功能特性为人津津乐道,同样,构建执行速度缓慢的缺陷也一直为人诟病。


近年来,随着优酷功能特性日益丰富,优酷的代码规模也急剧增加,同时,庞大的代码规模也带来了构建耗时的不断增加。整包构建耗时一度高达 35min,严重影响集成与迭代效率。因此构建速度优化势在必行。截止 2021 年 11 月份,优酷构建耗时优化取得较为理想的优化结果(如下),现将构建速度优化的实践方案记录成文。



方案与收益统计图:


优化思路

技术优化类项目一般采用照设定数据指标、技术优化、成果防腐化三个维度展开。套用技术优化类项拆解可知,我们需要完成如下三个子项目:


  1. 设定数据指标:即收集与选取核心优化的数据指标,体现成果价值。本文选取构建耗时、构建失败率、小时维度构建次数等指标作为成果优化的数据支撑;

  2. 技术优化:通过影响构建速度的影响因素可知,包括软件与硬件两部分,所以构建速度优化可分为软件优化与硬件优化两大方向;

  3. 成果防腐化: 即维持技术优化指标不恶化,保障优化成果。


接下来,我将按照设定数据指标与结果防腐、技术优化——软件优化、技术优化——硬件优化三个部分展开。


优化方案

设定数据指标与结果防腐

优化类项目需要建立健全相应的数据指标体系,借由数据评判体积优化项与优化方案进行有效性判定。进行构建优化前,笔者基于阿里巴巴 Aone FaaS( Severless 服务)平台搭建了数据评判与监控大盘。该大盘有构建类型、构建时间、构建成功率、构建任务耗时等多项指标,满足构建优化项目需要根据类型、任务频率、高耗时任务排查的需求。


完成相关数据能力建设后,通过构建关键数据指标——构建耗时与构建成功率的追踪和分析,进而得出构建耗时的主要影响因素为高耗时任务,构建成功率的主要影响因素为不合理的构建任务。因此,我们可以通过高耗时任务报警与不合理任务报警,快速发现并分析构建速度恶化情形,进而保障构建耗时优化成果。

软件优化

构建侧去 atlas

Atlas 是伴随着手机淘宝的不断发展,进而衍生出来的一个运行于 android 系统上的容器化框架,我们也叫动态组件化(Dynamic Bundle)框架。它主要提供了解耦化、组件化、动态性的支持。覆盖了工程师的工程编码期、Apk 运行期以及后续运维期的各种问题。


依托于深度定制的产物结构与高度复杂、深度 hook 的运行时框架,Atlas 可以视为移动端 OSGI 实现方案与组件化方案。但随着优酷移动端架构调整与自研远程化方案落地,Atlas 运行时框架逐渐丧失了 OSGI 框架作用,遂在运行期去除 Atals 框架。


当运行期将 Atlas 依赖去除后,Atlas 的复杂构建流程(如下图所示)也失去了存在意义。随即,优酷启动了构建侧 Atlas 去除项目,目标是将 Atlas 构建插件去除、构建原生化、纯净化、精简化。通过产物原生化、构建任务清理、工具链升级等一系列动作,在完成了构建侧 Atlas 去除目标的同时,构建性能也有部分提升。


收益:debug 包构建耗时降低 3min 左右。release 包构建耗时降低 4min-5min。


gradle 升级和 android gradle plugin 升级

gradle 团队一直在持续优化 gradle 的构建速度等性能指标, 同时 google 团队也在持续优化 android gradle plugin 构建工具性能。为了进一步提升优酷 android 端构建性能,决定对优酷 android 构建系统进行升级,将 android gradle plugin 构建工具版本由 3.0.1(2017 年)提升至 3.4.3(2019 年)版本,将 gradle 构建工具由 4.4(2017)至 5.5 (2019 年)版本。



对比升级前后构建耗时,可以发现构建工具升级后,性能提升主要源于三个方面:


  1. 随 android gradle plugin 升级,aapt2、proguard 等构建工具也进行了升级,这部分工具升级后,构建性能有小幅提升;

  2. 更好任务排布与并行化机制:升级 gradle 与 agp 后,agp 3.4.3 版本进行了签名、压缩、对齐任务的整合优化;

  3. 配置按需加载与异步化策略:android gradle plugin 3.4.3 采用资源的异步加载策略,即 configuaration 阶段仅做依赖拉取工作,不再进行产物的解压、过滤、合并工作,这样可以有效避免 io 拥塞问题,避免 cpu 忙等现象。


收益:debug 包构建耗时降低 2min 左右 。release 包构建耗时降低 4min 左右。

dx 构建优化

升级到 android gradle plugin 3.4.2 版本后,agp 新增了三个个 dx 构建参数,经过测试可以显著提升 dx 处理 class 文件速度。经过测试 设置如下三个属性降低构建耗时。


android.dexingNumberOfBuckets=16 android.dexingWriteBuffer.size=256 android.dexingReadBuffer.size=256
复制代码


仔细阅读 agp 源码可知,这几个参数构建构建内存中 dx 缓存大小、dex 读取写入片大小。默认 dexingNumberOfBuckets 为 cpu 个数的一半、读取写入大小为 1KB。这样就造成高 io 情形下,cpu 忙等情形。采用降低磁盘写入次数、增加缓存方式能够明显降低构建耗时。


收益:debug release 包构建耗时降低 3min 左右。

冗余任务整理

随着我们不断迭代、平台升级,一些 构建任务、构建功能等已经废弃,但由于构建系统的特殊性——无产物回滚能力,导致构建系统的任务一直处于单增状态。且由于构建系统高风险、低收益、逻辑功能复杂陈旧的特点,导致构建速度治理动力不足。


针对上述问题,通过构建逻辑梳理、构建配置项清理、 单任务调试等手段,逐步摸清构建每个构建任务的功能,并对 postPackageDebug 等 30+ 无用任务进行清理、对 transform 管理、任务管理等核心功能进行简化。下表为构建冗余任务清理列表。



收益:debug 包构建耗时降低 15s+ ,release 包构建耗时降低 20s+。

任务 pipeline 化

gradle 采用任务情形进行构建任务排布,基于这一拓展特性可以对产物进行后置处理。例如对 apk 后置处理有渠道处理、arsc 处理、对齐、签名、分包处理、图片压缩等任务,每一个任务都需要 apk 进行反复的解压、压缩、拷贝操作,浪费 cpu 、系统 io,徒增构建耗时。


为了降低 apk 构建耗时、简化 apk 产物操作复杂,我们对现有任务进行重整与拓展、实现了一种低拷贝、一次解压、一次压缩的产物 pipeline 处理机制,下图为构建过程 apk 后处理机制流程图。



收益:debug 包耗时降低 21s,release 包耗时降低 11s。

构建模版优化

按照用途区分 android 有多种构建变种,debug 版本、release 版本、远程与非远程等。对于开发阶段来说,一些插件的优化功能如 turbo dex 缩减、7zip 压缩完全无必要,可以直接禁止掉。


收益:debug 缩短 1-2min 左右,release 包无变化。

缩减代码规模

构建耗时中 java 代码混淆耗时约占整体构建耗时的 60%,同时混淆耗时与代码规模正相关。所以构建耗时与代码规模成正相关关系。


代码规模的膨胀一部分来源于业务扩张,一部分来源于冗余代码的工程腐化。自 2020 年下半年至 2021 年上半年期间,优酷进行了常态化的包体积治理,包体积取得了较为优异的成果,代码腐化问题也得到了部分缓解。


如下图所示优酷 android 端自 2020 下半年至今,可知 android 端 java 代码规模降低 25%,构建速度贡献约为 45s+。



收益:release 包构建耗时降低约为 45s+。debug 包构建耗时约为 5s-10s。

硬件优化

私有构建租户池

采用 iostat、tsar 等 linux 性能分析工具对优酷 android 端构建过程分析(如下图)可知。整个构建流程 cpu io-wait 现象严重,即构建过程中存在大量的 io 操作,由于构建机器 io 性能不足,导致构建耗时偏长, 侧面印证软件优化中降低 io 能够构建速度的有效性。



针对 io 瓶颈问题,主要有两种解决办法:采用 buffered io 处理、提升 Io 性能:


  1. 首先,仅保留 agp 插件进行构建,发现并无构建速度明显提升。证明:自定义插件无 io 优化空间;

  2. 其次,对 android 构建流程分析,io 碎片化写入较少,所有采用 buffered io 处理 io 瓶颈,优化空间不大;

  3. 最后,通过采用使用 SSD 替换机械硬盘效果较好。物理机构建比较数据如下:



收益:debug 减少 5min 左右,release 包减少 10min。

总结

综上所述,为了维护构建速度优化的成果,我们可以进行如下方面的工作:


  1. 为了满足数据指标设定与构建优化防腐的需求,我们需要设置构建优化指标,建立合理的数据评测体系;

  2. 通过对构建模板拆分、冗余任务清理、gradle 升级和 android gradle plugin 升级、合理设定构建相关参数——dx 构建优化等软件优化手段,我们可以获得大部分构建速度优化成果;

  3. 硬件优化部分需要建立构建流程关键瓶颈的分析上,各应用构建瓶颈可能不同。


受限于技术手段与稳定性问题, 构建速度优化还有如下未完成部分。


  1. 混淆规则控制与清理:混淆任务执行速度与混淆规则数量存在正相关关系,不合理的混淆规则会导致混淆任务耗时增长;

  2. 工程腐化程度治理:无用代码规模是工程腐化程度的重要标志,同时无用代码规模是影响构建速度的重要因素。但是如何治理大型项目的工程腐化程度,是应用架构以及全体应用开发需要探索的下一个重要课题;

  3. r8 构建优化:通过对 android dex 构建工具链——r8 的升级测试发现,优酷 release 包构建有较为明显的构建速度提升。但由于部分 google bug 导致 r8 优化 delay。


未来,优酷技术团队也将针对上述问题,持续优化构建耗时,欢迎大家随时与我们交流讨论。


【相关文档】

  • linux 性能优化指南:https://www.processon.com/view/618255cf1e08536d882c8afb?fromnew=1

  • r8 相关问题:https://issuetracker.google.com/issues/192304366?pli=1

  • Atlas:https://github.com/alibaba/atlas


我们招聘啦!


优酷 — 技术中心 — 架构团队招人,描述如下。

【职位描述】

  1. 负责以优酷为核心的 android 基础架构工作,包括基础框架、中间件等。

  2. 负责 app 的稳定性、性能、包瘦身等长效治理工作,提升基础用户体验。

  3. 研究移动端前沿技术工程化,以及技术趋势探索。

  4. 解决各类疑难问题,支撑业务快速、稳定、高效迭代。

【职位要求】

  1. 熟悉 Android SDK、Framework 等基础技术,并有较好的源码分析能力。

  2. 精通 Java 语言,基本功扎实,有 Kotlin、C/C++开发能力者优先。

  3. 对 Dalvik/Art 虚拟机中,任意部分有经验者优先。

  4. 有关键技术选型、疑难 Bug 修复、内存优化等经验者优先。


简历投至方式:yanjiao.syj@alibaba-inc.com


关注【阿里巴巴移动技术】微信公众号,每周 3 篇移动技术实践 &干货给你思考!

发布于: 22 分钟前阅读数: 4
用户头像

还未添加个人签名 2018.07.07 加入

阿里巴巴移动&终端技术官方账号。

评论

发布
暂无评论
优酷 Android 构建速度优化实践