美团:移动持续集成在大众点评的实战解析

向作者提问
美团技术团队官方账号
查看本场Chat

2018年08月15日,周三晚20:30,大众点评 iOS 技术专家何志聪、大众点评 Android 技术专家邢轶带来了主题为《MCI:移动持续集成在大众点评的实践》的交流。以下是主持人张义整理的问答实录,记录了作者和读者间问答的精彩时刻。


内容提要:

  • 组件这么多,依赖也这么多,是不是解耦没做好?
  • MCI 如何处理庞大组件库涉及到的版本依赖冲突的?
  • 构建时间越来越长,遇到瓶颈怎么办?
  • 刚才您说的随着动态化的发展,构建时间会被控制只是从侧面控制了时间,并没有从根本上解决构建的问题,有没有办法从其他方面去控制编译时间?比如减少预编译方法的使用等等?
  • 有一点好奇,对于 Android 来讲,二进制集成也就是 SO 相关的代码提前编译好,但其余的依赖库还是得源码编译。如果这些依赖库都做成 AAR 的方式,那么混淆文件就要统一在主程序里面配置,这样是不是不好?
  • 你们这套东西用了多久?目前这套东西在线上的效益是怎么度量的?
  • 图中这个依赖关系是怎么处理的?
  • 修改多线程下载的方式能说下吗?
  • MCI 的静态代码检查用的是什么工具,Infer,Lint 和众多工具中选用的是什么,原因是什么?
  • 大众点评这套自动化会开源出来吗?如果团队进了新成员学习成本有多高?
  • 有可能产品的一个需求就导致整个架构改动的很大吗?
  • 这个拆分功能模块的工作,是开发过程中自然形成的,还是在类似 Design Review的时候规定的?简单来说,各种功能模块最开始是怎么形成的,以及拆功能的时候,拆到哪里是个头?
  • Gitlab-CI 与 CD 是通过哪种方式集成的?插件吗?
  • 二进制方式集成会造成无法调试,请问这是怎么解决的?

问:组件这么多,依赖也这么多,是不是解耦没做好?

答:我们大众点评的业务复杂度之高是有目共睹的,所以从底层库到上层业务组件库都拆分的非常细。拆分的足够细之后一方面某个库由一个人或者两三人来维护,这样把团队间耦合影响降低最低。另一方面组件解耦拆分的足够细能快速方便 App 的复用,任意一个新 App 只要在组件池中按需索取基础组件库,就能快速搭建起基础设施,业务方只需开发维护业务组件库就可以。所以依赖多不是解耦没做好而是做的过分了,当然我们的组件库确实是非常多的,这和我们的业务多也有很大的关系。尽管组件库很多,但是 MCI 能很好的完成组件的发版集成工作。


问:MCI 如何处理庞大组件库涉及到的版本依赖冲突的?

答:确实,点评 App 目前的组件库近千,在集成时一定会存在不同版本所导致的行为、配置不一致而导致的编译等各种问题。目前,集成项目通过集中管控所有接入的组件库版本号,结合静态分析来屏蔽组件库中可能存在的动态依赖的配置。


问:构建时间越来越长,遇到瓶颈怎么办?

答:如果业务规模一直扩大,理论上代码越来越多,项目构建时间是会越来越长,优化的手段也会越来越少。但实际上现在随着 App 动态化的发展趋势,比如 RN、Weex、Picasso 等,这些动态化的方案可以大量的减少业务代码。所以未来 Native 代码不会一直增加,相反随着动态化覆盖程度的提高 Native 的代码会减少,构建时间会得到有效控制。


问:刚才您说的随着动态化的发展,构建时间会被控制只是从侧面控制了时间,并没有从根本上解决构建的问题,有没有办法从其他方面去控制编译时间?比如减少预编译方法的使用等等?

答:办法总比困难多,当然还有很多其它优化手段,比如增量编译,或者像你说的减少预编译方法的使用。


问:有一点好奇,对于 Android 来讲,二进制集成也就是 SO 相关的代码提前编译好,但其余的依赖库还是得源码编译。如果这些依赖库都做成 AAR 的方式,那么混淆文件就要统一在主程序里面配置,这样是不是不好?

答:混淆文件的配置最佳实践确实是在主工程统一控制更合适,主要为了:

  1. Crash 反解定位;

  2. 统一管控避免全局问题。

针对2的补充,比如全局配置污染。


问:你们这套东西用了多久?目前这套东西在线上的效益是怎么度量的?

答:4、5年了,以前是基于 Jenknis,现在基于 GitLab CI,一直在做持续优化。MCI 主要是用来保证大型团队间的合作开发,保证研发流程不被某次错误集成打断。MCI 通过自动化的发版集成以及自动化打包将研发从 CI 流程解放出来,提升研发生产力。


问:图中这个依赖关系是怎么处理的?

enter image description here

答:基本原理是在递归解析项目依赖时,通过构建提供的 Resolvedep Hook 来拍平依赖,间接依赖全部舍弃。


问:修改多线程下载的方式能说下吗?

enter image description here

答:我们是对 Cocoapods 做了定制,可以下载 Cocoapods 源码找到对应下载代码,修改默认线程支持。


问:MCI 的静态代码检查用的是什么工具,Infer,Lint 和众多工具中选用的是什么,原因是什么?

答:目前 MCI 是运用点评自研的静态分析工具 Hades 来做代码检查工具的。主要原因是相对业内提供的工具,Hades 的接入门槛更低,基于对代码的 AST 分析后自定义一整套的自定义检查,可定制性更高,这会在后续的技术文章中详细阐述。


问:大众点评这套自动化会开源出来吗?如果团队进了新成员学习成本有多高?

答:暂时没有开源计划,我们的持续集成系统本身也是基于开源的 GitLab-CI 做的。MCI 分享的主要目的是在持续集成系统基础上针对移动项目做的一些优化策略和方法供大家参考,和业内的同行进行交流学习。团队新成员可以通过我们的一键发版集成工具来完成组件库的 CI,MCI 在正常情况下对开发是透明的。


问:有可能产品的一个需求就导致整个架构改动的很大吗?

答:就点评 App 发展到目前的情况来说,架构的演进一直是渐进式的,而且可能会有所“超前”,咱们研发一直持续保持紧迫感,收集并优化业务研发过程中的痛点,包括 MCI 本身也是。


问:这个拆分功能模块的工作,是开发过程中自然形成的,还是在类似 Design Review 的时候规定的?简单来说,各种功能模块最开始是怎么形成的,以及拆功能的时候,拆到哪里是个头?

答:最初大众点评 App 项目也是所有代码在一个工程中的。后面做了组件拆分,分为基础 SDK、中间层和业务层,主要根据组件功能来拆分。拆分的目标是解耦开发,能满足团队间合作开发不互相影响即可。


问:GitLab-CI 与 CD是通过哪种方式集成的?插件吗?

答:集成目前主要是通过 Gitlab-CI 和 Runner 配合来做。CD 会有多个场景,比如准入后触发打包、特性功能触发打包等,主要通过 Hook 或者打包任务来执行。


问:二进制方式集成会造成无法调试,请问这是怎么解决的?

答:这里其实是两个问题,一是二进制方式集成怎么做检查;e二是本地开发怎么调试。

  1. 二进制方式集成怎么做检查:我们自研了一套 Hades 静态检查体系,Hades 是组件发版过程中根据 AST 生成代码描述信息,然后在集成过程中基于此做检查;

  2. 本地开发调试:我们支持想要调试的 POD 改为源码集成,通过部分二进制部分源码的集成方式可以调试你想调试的代码。


本文首发于Gitchat,未经授权不得转载,转载需要与GitChat联系。

微信扫描登录