[关闭]
@xuemingdeng 2017-05-14T12:01:30.000000Z 字数 3538 阅读 889

单体代码仓库:Uber的Android代码仓库演化史

单体代码仓库 运维

Uber技术日开幕式上,软件工程师Aimee Lucido呈现了一个有关Uber Android代码库历史的演讲。在这篇文章里,她继续展开说明Uber为什么要构建一个单体仓库来支持Uber的Android开发。

今天,你们要开始构建一个全新的Android应用,对于你们来说,开头部分总是最困难的。那么要如何开始呢?

如果你们跟我一样,那你们一定也是先在Android Studio里创建一个新的项目,然后创建一个主Activity,配置Gradle,或者再创建一个git仓库,这样其他人就可以与你一起合作开发这个应用。那么恭喜!你的代码结构就组成了第一个版本的Uber搭车应用。

此处输入图片的描述
我们使用一个大纸箱表示Uber的第一个Android代码基库:一个装着代码的大箱子。

我们在2010年启动了我们的第一个Android打车应用,那时我们还是一个小公司。Uber的工程团队只有寥寥数人。我们有一个合同工负责Android平台的开发,而且(如果你能够想象得到)我们甚至还没有Android的司机应用。我们的光杆Android工程师基于一个单独的代码库开发了打车应用的第一个版本:一个装着代码的大箱子。

在早期,使用单独的代码仓库来创建一个新的应用有几个好处:

几年之后,Uber的Android开发有了小规模的扩张。到了2013年,我们聘请了第一个全职Android工程师,在这一时期,我们的工程团队已经比之前翻了一翻。也就是从那个时候,我们才开始开发第一个司机应用。

开发司机应用让我们有机会对我们的代码基库结构进行改进。打车应用仍然放在单独的代码基库里,不过我们将一些可重用的组件抽取出来,因为我们已经拥有了必要的资源和工具来做这件事情。核心的代码仍然放在它自己的仓库里,不过我们构建了一个类库,包含了两个应用都要用到的公共组件。

到了2014年,我们的增长规模要求我们去寻找其他不同的解决方案。Uber的工程师已经超过一百个。Android工程团队的工程师也从一个变成了八个。随着工程师数量的增长,我们的代码基库规模也在增长。

我们看着前行的方向,我们意识到,如果我们不做出一些改变,我们将会碰到如下几个问题:

所以,在2013年到2014年期间,为了解决这些问题,我们做出了一系列改变,我们迁移到了多仓库的代码基库。2013年,我们使用IntelliJ和Maven代替了Eclipse和Ant,这样我们就可以从服务器上拉取依赖包,并将我们的包仓库拆分成20多个更小的独立仓库。(例如,网络相关的包被移到自己的仓库里,然后应用程序在编译时通过Maven将它们拉取到本地。)同时,我们改用Gradle构建脚本,迈出了向多仓库侵袭的第一步。

此处输入图片的描述
我们使用几个纸箱表示多库代码仓库,Uber在2013年将代码基库转成这种结构,以便满足不断增长的用户需求。

Uber的多库代码基库由一些小代码基库组成,每个小代码基库代表了一个单独的离散想法,包含了一些类库,打车应用和司机应用在编译时拉取这些类库。每个代码库就像是一小箱子的代码,包含了自己的IDE项目文件、git仓库和构建脚本。多库代码仓库是一种稳固的具有前瞻性的架构,解决了构建时间长、功能特性耦合和Master分支遭到破坏的问题。

现在的问题变成:为什么我们不是一开始就使用多库代码仓库?一句话:成本。将功能特性拆分到独立的仓库需要大量的时间,而且需要很多专家来完成。它需要很多领域的知识,比如Maven、Gradle、VPN和类库管理。这种知识的投入也只有在公司的规模增长到一定程度的时候才是值得的。

在将近三年的时间里,我们伴随着多库代码仓库结构一起成长。但到了2016年,我们的多库代码仓库开始出现瓶颈,我们的开发人员开始面临新的问题:

那么我们是怎么解决这些问题的?

我们的解决方案:使用单体仓库,一个包含了多个独立项目的代码仓库。一个代码基库包含一个单体仓库,就像我们最初的打车应用那样。不过与打车应用不同的是,这个箱子里包含了多个逻辑组件,它们是相互独立的。现在,我们可以在工具和架构上投入时间和资源,来修正大型单体仓库的缺点:

这看起来花费了不少功夫,事实确实如此。目前还没有开箱即用的单体仓库解决方案,因为很少有公司可以达到需要使用单体仓库的规模。我们现在有了时间、专家和资源来构建工具,防止那些在2013年出现过的痛点再次对我们的生产力造成破坏。

Uber花了数年的时间才达到了目前的开发状态。当我们还是一个由几个工程师组成的团队时,我们没有时间和资源来创建Submit Queue或者搭建Buck。不过,我们早期的洞见促进了架构决策,让我们可以快速地伸缩。现在,我们有了更进一步的发展,我们可以在开发上投入更多,确保未来的服务增长是无缝和高效的。

提升开发者的生产力是块难啃的骨头,但却非常重要。随着每一次小步跑的进步,我们不仅让Uber变得更好,也让整个Android社区变得更好。

查看英文原文: THE JOURNEY TO ANDROID MONOREPO: THE HISTORY OF UBER ENGINEERING’S ANDROID CODEBASE ORGANIZATION

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注