iOS程序员

Xcode Server 持续集成与整体架构

随着WWDC2015的落幕,有很多新的技术和变更一涌而来,这其中便有关于Xcode Server的,它将会以RESEful的方式来公开API,与之比较相关的,应该就是Xcode原身支持了UI Testing、Code Coverage,这些都是非常棒的功能。如果你致力于打造更强大的移动开发团队、更稳定的移动产品、更迅速的版本迭代,那么或许本篇文章可以给你提供一些思想。

Xcode Server 的基本功能

Xcode Server作为苹果官方的一个持续集成方案,它宿主在OSX Server中,主要提供了以下几个功能:

  1. 自动构建项目,反馈构建中的错误(Error)和警告(Warning)。
  2. 自动在多种终端和多种模拟器上执行单元测试、UI测试,并反馈测试结果,代码覆盖率。
  3. 可以自动打包项目,按指定证书签名,进行相应归档。
  4. 提供触发器功能,可指定集成前集成后在服务端执行一段自定义脚本。
  5. 提供RESTful API,可在第三方应用系统中进行集成。

大体也就这些功能点,下面简单介绍下,如何进行使用。

连接 Xcode Server

要使用Xcode Server,首先我们要连接到相应的服务器,点击Xcode中的Xcode->Preferences...->Account

填写完相应的服务器地址和用户名密码,即可连接到该服务器上,并且在Xcode的Report navigator上可以看到目前服务器上已有的Bot和相应的集成记录:

当然,如果你从未添加过Bot,则Report navigator上是不会有这些记录的,接下来我们创建一个Bot。

创建 Bot

所谓Bot,就是一个机器人,它负责按照你的设定,进行一些重复性工作。要想让项目能够被Bot识别进行后续的集成操作,则必须将它的Scheme标记为Shared的,可以在Xcode的Product->Scheme->Manage Schemes...进行操作:

这里需要注意下,一个Scheme对应一个Bot,也就是说,如果要创建针对同一个项目的不同配置构建(如Debug、Release),则需要配置多个不同的Scheme;而针对同一个项目的不同环境进行构建(如证书签名、支持的CPU架构),则应该配合使用不同的Target。

当我们将Scheme标记为Shared后,就可以创建相应的Bot了,点击Xcode中Product->Create Bot...,第一步选择要进行持续集成的Scheme:

上图中红圈部分仅当该Scheme没有被标记为Shared时,才会出现,勾选这里的Share scheme会自动将该Scheme标记为Shared。这里填写下Bot的名称,进入下一步即可。

第二步是和源代码管理的集成,按照提示完成相应验证即可。接着进入下一步:

这一步是比较关键的一步,选择它的执行频率,可以是周期性的每次提交代码时手动这三种。

然后可以配置它要执行的一些动作,是否对项目进行analyze,是否执行测试和分析代码覆盖率,是否进行归档和创建用户可安装的产品(app或ipa)。

这里也可以配置DebugRelease,和清理策略。

后续几步也是非常简单,如果你选择了要执行测试,则会让你配置要在哪些设备和模拟器上进行测试。然后便是触发器配置,最后便是执行创建了。注意,创建完毕后,Xcode提示你需要将该Bot的配置提交到源代码管理远程仓库中,否则Xcode Server将不会进行任何集成操作。

执行和查阅相应 Bot

创建完毕并提交后,Xcode Server会立刻进行集成操作,在Xcode的Report navigator中可以看到相应进度和执行结果:

Summary:

Tests:

Coverage:

关于Xcode Server的基本使用,大体就介绍到这里,如何更好的将其应用到生产环境中,将是接下来的话题。

持续集成工作流

在日常的协同工作中,我们的最终产品大体会经历下图的几个阶段:

这是一个不断迭代的过程,一旦有新的需求变更,整个流程会重新运转一遍。这个流程本身没什么,而在缺少了持续集成的支援下,会带来以下问题:

  1. 为了确保新的版本迭代不会对旧的结构造成破坏,测试人员需要进行大量的回归测试。
  2. 业务开发人员的代码提交需要一定的人力进行Code Review,加之没有硬性的质量指标,所有项目中几乎不会包含一句单元测试代码。
  3. 非技术高层管理人员,对开发的质量管控缺少一种可靠的知晓途径,一般只能靠口口相传。
  4. 不同项目的发布、上架缺少一种统一的管理方式,仅靠少数开发人员进行手动操作。

当然,问题肯定不止这些,但这些最具代表性,为什么会带来这样的问题?在非互联网企业中,这些问题可能永远都不会对业务造成影响,而在一个互联网企业中,这些应该是生产流水线的基本管理,在质量和细节的把控下,我们不应该容忍这些空缺。随着项目的不断推进、迭代,这些问题最终会导致管理上的失控,代码也会出现僵化,这些都不是我们想看到的。那么,为什么会带来这样的问题?

我们缺少了一套完整的持续集成工作流,毕竟一个项目不可能只有一个开发人员完成,在我们对其它模块未知的情况下,需要通过不断的集成来验证我们的更改,树立我们的信心,并尽早的发现错误。在持续集成的工作流中,我们应该确保任何时间都是可以发布和部署的,这样严格限制了开发人员的代码提交,也限制了开发人员必须完成自我测试。以下是持续集成的一些原则:

  1. 所有的开发人员需要在本地机器上做本地构建,然后再提交的版本控制库中,从而确保他们的变更不会导致持续集成失败。
  2. 开发人员每天至少向版本控制库中提交一次代码。
  3. 开发人员每天至少需要从版本控制库中更新一次代码到本地机器。
  4. 需要有专门的集成服务器来执行集成构建,每天要执行多次构建。
  5. 每次构建都要100%通过。
  6. 每次构建都可以生成可发布的产品。
  7. 修复失败的构建是优先级最高的事情。
  8. 测试是未来,未来是测试。

基于Xcode Server这样的基础设施和所面临的问题,以下是我觉得比较合理的系统架构:

  • Xcode Server服务:基于Xcode Server提供的RESTful API进行适配和包装的一个服务单元,支援其它系统。
  • 其它持续集成服务:非Xcode Server集成方案的持续集成服务,用于其它开发环境的持续集成,比如Java、.Net等。
  • CI系统:集成所有实现了标准CI约定服务接口的持续集成服务,提供相应的管控界面,并集成风险管控、数据分析、发布等一些其它服务。
  • 风险管控系统:提供风险管控服务,对事故进行分级和预警。
  • 数据分析系统:负责对收集的数据进行趋势分析,并提供查询和报表。
  • 发布管理系统:提供应用发布服务,集成标准发布接口,统一管控发布流程。

上面简略的对这些系统做了介绍,接下来我们基于这样的一个系统架构,来探讨下一些日常的工作流。

开发

首当其冲的自然是开发,开发是最核心的产出,也是对质量影响最大的一个环节。在持续集成系统、风险管控系统、数据分析系统的三大制约下,开发人员需要对代码提交格外小心。自然,如果将测试覆盖率也纳入绩效考核中,则相应模块开发人员自然会尽可能的完成更多的测试,这对最终产品的稳定性无疑是有了更好的保障。

所以开发需要做的便是:

  1. 撰写代码和测试
  2. 执行测试
  3. 本地构建
  4. 提交代码
  5. 查看CI系统集成情况

测试

有了CI系统,测试人员的工作量应该会大大降低,特别是在有了UI自动化测试的支援下(这是一个讲究科学的时代,纯手工的操作是低效且容易出错的)。而在进行回归测试的时候,这种好处会更加明显。

所以测试人员要做的便是:

  1. Review CI系统中的测试用例
  2. 撰写自动化和手工测试用例,并提交自动化测试到CI系统
  3. 督促开发人员修复测出来的BUG

发布

因为持续集成的原则就包含了随时可发布,所以,发布便是在发布系统中挑选CI系统中的构建,点击发布即可(注意发布系统CI系统的协作关系)。

管理

管理人员基本不会关心CI系统的一些基本情况(他不可能去看你写的测试用例是否正确),因为有更高层的风险管控数据分析发布管理三大系统。

  • 当自动构建持续失败到一定的次数,风险管控系统会自动发布风险预警,并通过各种渠道通知到相应的人员。
  • 数据分析系统会对构建的趋势进行分析,包括成功率、失败率,这有助于管理人员进行一些决策。
  • 数据分析系统会对开发人员进行分析,包括代码提交率、测试覆盖率、成功率、失败率等,站在数据的角度来确认一个开发人员是否合格。

现在,回头看看最先前提出的那几个问题,是否都得到了很好的解决?那么接下来的问题,便是如何构建这样一套系统。试想一下,如果风险管控系统数据分析系统仅仅为CI系统服务,那这两个系统就太鸡肋了,还不如直接集成到CI系统中,但我并没有这么做,因为我将他们都定义为服务化的系统。构建一套完整的互联网企业内系统,我们需要服务化的架构,这便是SOA

浅析 SOA

本不打算涉及SOA的,但最终还是谈到了它,不得不说,我觉得它太重要了。一个成熟的互联网企业,离不开服务化的架构,这无论是对现有系统的复用率还是前后端实现分离都有莫大的好处。构建一个强大的SOA体系,前期是需要一定量的投入,但我觉得这对企业的未来布局有着非常重要的作用。

以下是我觉得非常基础的一个SOA架构分布图:

上图中,有五大模块,基本上在SOA的架构中都很常见,这里简单说明下:

  1. Infrastructure 基础设施:这是最基本的服务,也就是说它不会依赖于任何其它服务(通过箭头的方向可以看出,这个模块只会输出服务),它们是构建系统时通用的基础设施。
  2. Base System 基础系统:这里是一些通用的基础系统,它们会依赖一些基础设施服务,同时也会对外输出相应的服务。这里的发布系统会依赖于CI服务,而CI系统会依赖于BI服务
  3. Business System 业务系统:该模块里,是一些对外的公开业务系统,比如一些支付、订单等。它们和基础系统一样,会输入也会输出服务。
  4. Client 客户端:这是最高层次的一个模块,它完全只会输入服务。比如Web客户端、APP、PC客户端等。
  5. Service Bus 服务总线:这是一个非常重要的横向模块,它穿插在前面四大模块中,主要负责服务的注册和发现,服务的使用者可以在服务总线上找到它们感兴趣的服务,或者提供一些自身的服务。

服务总线无疑是整个SOA的核心所在,所以针对它的设计上,需要下足功夫,以下是我觉得需要注意的地方:

  1. 分布式事务的支持,这是非常重要也是SOA存在的一个价值点。
  2. 服务元数据支持,在服务发现上,应该是可以获取类似于SOAP协议的元数据,但这里不推荐使用SOAP。我觉得可以参考telegram的TL Language,可以参考我的这篇文章。这样我们可以构建工具来生成各平台的服务客户端代码,方便服务集成。
  3. Gateway,这是在服务调用者和被掉服务间的一道关卡,这无疑也是一个技术指标,它需要做到路由、限流、隔离、监控、熔断等。
  4. 多数据协议支持,这是比较基本的,也是非常重要的,常见的有:JSON、XML。
  5. 多种通讯方式支持,和上面一样,常见的有REST、SOAP、XML-RPC等(如果足够强大,还应该考虑WCF和EJB)。

SOA是互联网企业架构的趋势,无论是大数据还是物联网都离不开它,所以,如果想成为一家一线的互联网企业,应尽早的朝这个方向发展。这里只是简略的提了下,SOA的内容还是相当多的,每个话题展开都可以进行长篇大论,市面上有很多讲企业架构的书也都讲的非常详细,所以,可以从那里了解更多关于这方面的内容。

总结

无论是持续集成还是SOA,在互联网企业中都是非常重要的,本文简略但比较完整的将这些内容进行了讲解,并就自身的一些认知做出了相应的设计。任何理论都不应该仅仅停留在理论阶段,否则它就是空想而已,所以,希望大家能够将从本文中获取的想法付之实践,从而总结出更有效、更实际的方法,也别忘记将它分享出来。

如果需要将Xcode Server与其它平台进行集成,下面是可以进行参考的网址:

那么,这篇就到这里吧!