[译]如何快速稳定地构建iOS应用

原文:3x3: iOS Build Speed and Stability

作者: Keqiu Hu   译者:杰微刊兼职翻译张万程 

Voyager项目是为了开发LinkedIn新的旗舰级手机应用,去年年初,我们开始在项目中实践3x3哲学:

一天发布三次,从代码提交到用户可以使用,不超过三小时。

虽然我们不能每三个小时向App Store发布一次,但我们每天可以多次构建员工使用的企业产品。“3x3”听起来很快很容易,但说起来容易做起来难。三小时一发布的节奏,让我们没有时间做手工测试,所我们需要一个通道:

1.从代码提交到产品发布,每个环节都完全自动化

2.可靠性要好,甚至要高于手工测试

3.速度足够快,能够适应我们三个小时的窗口期

4.稳定性,确保每个合法提交都会被发布

今年年初的时候,Drew Hannay在他的博客,3x3:加速手机应用的发布中简要介绍了手机应用3x3哲学。围绕快速和稳定构造,我们将深入探索3x3在iOS应用开发中的应用。

第一部分:速度

为了获得一个从代码提交到发布小于三小时的通道,我们通过重构Swift代码,加速编译速度,加速我们的UI测试框架,构造和测试并行等手段,以优化我们的构造通道。

加速代码编译

我们选择Swift做为新的旗舰级应用Voyager的主力开发语言,从最早的1.0到2.0随着Swift的不断升级,我们的项目也在不断演变。

在Voyager项目早期,我们非常享受Swift的易用和先进的功能,但漫长的编译时间长长令我们沮丧。随着起来越多的代码提交到我们的iOS代码库(每天大约60次提交), 我们发现即便只有少数文件发生变更,编译时间也呈指数增长,从数秒到30分钟左右。更糟糕的是发布构建时间比调试构建时间更长,通常需要2个小时。秉承“测试要与开发同步”的原则,我们要另外再花两个半小时来写150个KIF测试。结果,我们需要花四个半小时完成从提交到发布的过程!

为了缓解开发者的挫败感,我们通过Apple开发者社区,Apple开发者论坛和公司合作伙伴关系努力与Apple工程师沟通。并就如何缩短我们的构建时间,获得了很多宝贵的反馈意见。 Jacek Suliga负责一个主要代码库的重构,将我们的工程分成不同的子项目和模块,用显式引用取代隐式引用。这使得调试构建时间几乎缩短了一半,发布构建时间从原来的2小时缩短到35分钟,从提交到发布时间缩短到3个小时。对于本地开发,我们为每个iOS开发人员购置了一台Mac Pro,以减少调试构建时间。

UI测试框架优化

构建时间优化之后,UI测试时间成为瓶颈。Jacek在 UI自动化:保持实用和稳定一文中介绍了我们如何优化开源项目KIF,让它可以5到10倍地提速。这大大缩短了测试时间,测试运行时间缩短了80%,只需要大概20分钟时间。然而,测试越来越多,一个月内增长了四倍,测试时间增长到80分钟,总时间增长到2个小时。

在对编译和UI测试框架做了优化之后,我们认为只有技术创新才能显著解决从提交到发布的时间问题,我们将重点放到了:分布式构建和测试。

分布式构建和测试

我们与基础设施团队密切合作,为iOS和Android提供分布式编译和测试支持。当我们将所有构建和测试任务分发到10台机器上,唯一的瓶颈就变成了发布构建时间,加上一些工具开销,需要35分钟完成。提交到发布的总时间下降到45分钟。使用更多的机器可以进一步提高构建时间,但是也会引入一些可靠性问题,我会在稳定性部分阐述

第二部分:稳定性

在我们的构建通道中,从提交到发布,有两个关键组件会影响整体稳定性:测试系统的稳定性和构建工具的稳定性。

1. 测试系统稳定性

在我以前的博客:测试稳定性 - 我们如何让UI测试变得稳定,我讨论了我们如何构建稳定的测试环境。主是是稳定的测试环境,从测试框架中移除不可预测的因素,净化我们的测试组件。请重温一下那篇博客,关于我们如何让我们的测试基础设施变得稳定的细节。

2. 工具稳定性


2.1 硬件稳定性

我们通过cfengine集中管理我们的机器池,现在我们有两类Apple硬件:

Mac Mini (2012年版)

①处理器 2.6GHz Quad-Core Intel Core i7

②内存 16GB 1600 MHz DDR3

③存储 1TB HDD

④Intel HD 显卡

Mac Mini (2014年版)

①处理器 3.0GHz Dual-Core Intel Core i7

②内存 16GB 1600MHz LPDDR3 SDRAM

③存储 512GB PCIe-based Flash Storage

④Intel Iris 显卡

有一次,我们看到建构池中出现内存问题,有10%的机器活动内存小于100MB,大量使用交换分区。当检查这些内存不够用的机器时,我们发现在后台有20多个长期运行的xcodebuild进程。我们意识到这是此前挂起的xcodebuild进程所致。

为了解决这个问题,我们采取了以下行动:

1. 添加重试逻辑,在运行新的任务前,清除所有挂起的xcodebuild进程。

2. 对有可能导致内存溢出的服务每天定期重启。

3. 对交换分区使用较多的机器设置自动报警。

2.2 Mac 系统构建环境稳定性

除了内存问题,我们偶尔也会发现机器上有运行iOS模拟器问题,这些问题影响了整体稳定性。一旦机器上出现模拟器问题,如果不正确处理,它会影响这台机器接下来的所有构建任务。我们曾经付出巨大的努力来解决模拟器问题(参见:企业级iOS持续集成管理),但当我们尝试解决这个问题时,发现还不如先前的效果,因为模拟器工具并不在我们的控制之中。

幸运的是,我们发现重启可以解决绝大部分模拟器问题。我们启动了一个叫PoolGuardian的项目,用来监控所有构建机器,并且定期检查是否有机器出现模拟器问题,如果发现有问题,它会重启这台机器,并且在重新使用这台机器前会做健康检查。

2.3 并行测试稳定性

分布式测试看起来很有前景,因为它确实解决了我们的速度难题,但是当我们遇到一些可靠性问题时,我们意识到它是一把双刃剑。

在我们的Mac系统工具链环境中,我们遇到一些Apple开发者工具链问题,包括间歇性编译崩溃,模拟器崩溃,模拟器重复性错误,和环境错误问题。总之,每天机器的稳定性大概在95%左右。看起来好像还不错,但是在分布式测试中,只有所有子任务全部通过,一个构建才能完成,确切一点说,10个子任务要全部通过。所以每加一个节点,总体可靠性下降到原来的95%,随着结点数的增加,整体可靠性呈指数下降。如果使用10个结点,工具链的可靠性下降到95%10 ≈ 60%。

为了改善上面提到的工具链可靠性问题,我们优化了我们的构建池,使用种种手段让我们的 Max OS X更加可靠。通过这些努力,工具链的稳定性从95%提高到略高于98%。加上其他结点,稳定性仍然有98%10 = 82%。这远远没有达到我们的预期—99%的可靠性。但是解决x10 = 99%需要 x = 99.9%,这就需要99.9%的机器可靠性,这需要更多的资源和精力。

同时,我们试图跳出这个怪圈,我们希望在高可靠性的同时,我们的构建通道可以快速完成提交到发布过程。然后我们有了一个突破:如果我们把所有任务都放到一个测试结点,同时使用多个模拟器跑测试会怎么样?基于这个想法产生了Hydra项目,Hydra的总体目标是:

1. 在一台服务器上使用多个模拟器并行跑测试,让构建时间提高5到10倍。

2. 启用不同模拟器之间的交互测试(iOS与iOS, Android与Android ,iOS与Android)

在这篇博客中,我只涉及第一个目标。下图是多模拟器测试架构。


当一个提交发生后,测试运行器会构建应用并启动5个模拟器用来组成一个模拟器设备池。构建完成后,测试运行器将查询测试集群,获取一个测试类列表。根据测试用例的数目,测试类会动态分配到20个单元中,并形成一个测试队列。一旦初始化阶段完成,设备池会不断地获取测试任务并运行。同时设备池有一个健康监测进程保证设备池的健康运行。一个测试任务结束后,测试成果和测试报告会被收集并上传到持续集成工具,等待下一个发布周期。

你可能会问,为什么我们选择运行5个模拟器,这是因为OS对每个shell会话的进程有个默认限制,在Mac Mini上是709。每个模拟器会产生大约70个进程。当我们添加300个MacOS系统进程,我们同时只需启动5到6个模拟器。我们曾经试图取消shell进程限制数,但是当超过700个进程时,OS环境会变得很脆弱。所以,权衡扩展性和可靠性,我们选择5个模拟器。

有了Hydra的帮助,我们的构建稳定性从最初的0提高到今天的90%,而且我们还在不断的优化它。下图是一个示例,我们会以我们的方式开源这个项目,敬请关注!


致谢

如果没有包括工具,测试,移动基础设施和其他LinkedIn团队的专业协作,我们不可能完成这些,谢谢大家。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,398评论 25 707
  • 《星期四》 今天是星期四 孕妇坠亡的事情还在继续发酵 城市的创文工作也还是抓得很紧 一天的单词量还没达成 口语只练...
    _阿花阅读 422评论 0 1
  • 一、类型:校园,友情及言情 二、基调:悲剧 三、全文字数:约15万字 四、内容的梗概: 1:起因:因某事两个女生认...
    迷鹿小姐阅读 410评论 8 3
  • “你说的道理我们都懂,正是因为做不到,我们才苦恼。你要告诉我具体的方法!” “不,你不想可不行啊。” 约在公元14...
    i期待阅读 563评论 0 0