发布新软件是一个复杂且漫长的过程。最新软件构建是否能成功,快速反馈是快速修复的根本。在产品生命周期中,缺陷发现得越晚,修复的成本就越高,难度也越大。
Azure DevOps 是一组可集成的软件项目管理服务及工具集,可作为完全托管的云开发产品使用,称为 Azure DevOps 服务(之前称为 Visual Studio Team services,VSTS),也可以作为内部开发产品使用,我们称之为 Azure DevOps 服务器(之前为 Microsoft 的 Team Foundation Server,TFS)。
无论是哪种格式,Azure DevOps 都可以自动化并优化软件构建进程。但对于更大更复杂的产品,Azure DevOps 的反馈周期可能太长。这篇文章将介绍如何将 Azure DevOps 构建进程的自动化功能与 Incredibuild 独特的进程虚拟化技术结合。充分利用 Azure DevOps 构建机器连接的网络或公共云中的所有内核资源,大幅加快编译速度,将每一台主机都顺畅地转换成一台拥有数百个内核和千兆内存的超级计算机。
Azure DevOps 是一套工具集,可以满足开发团队的全部需求,从需求收集和工作管理,到软件开发、版本管理、单元和验收测试,甚至软件打包、构建和部署。Azure DevOps 与微软自己的集成开发环境(IDE)Visual Studio 进行了本地集成,并致力于在默认设置下构建软件,这些软件由微软支持的软件语言编写而成。但是 Azure DevOps 也完全集成了其他 IDE,因此几乎可以构建任何软件语言的产品。
Azure DevOps 构建进程通过触发由一个或多个阶段组成的管道来进行管理,这些阶段依次组织管道中的作业。每个作业在一个 Agent 上运行,该 Agent 可以是 Microsoft 托管的(即完全托管的维护和升级)或自托管的。作业包含多个步骤,可以直接在 Agent 的主机上或容器中运行。步骤,即预打包的任务或脚本,是管道中最小的构建块,存储为可读的 YAML(YAML Ain’t Markup Language)文件。
Azure DevOps Agent 通常为每一个单独作业提供一个 CPU 内核,大部分作业按顺序执行。由于管道中很少是并行运行的,因此要提高性能就需要提高 Agent 的 CPU 速度,以处理计算密集型进程,并提高其 IO 能力以处理 IO 密集型的进程,例如对文件系统或网络的读写。
然而,今天的多核 CPU 只有在并行运行时才能获得更高的性能。尽管双核 CPU 可以运行的操作是单核CPU的两倍,但它必须并行运行,一次两个,才能实现速度翻倍的目标。因此,作为软件开发人员,我们必须尽可能地分解计算密集型的操作,通过并行运行,最大限度地提高进程速度。
在本节中,我们将研究改进 Azure DevOps 构建进程、更好地使用多核 CPU 的不同方法。我们将分别说明每种方法的优点、成本和劣势,重点聚焦计算密集型操作。
计算密集型活动的常用并行化处理
尽管某些软件开发架构可以轻而易举地实现并行化处理,甚至开发人员也丝毫察觉不了,但一般来说,并行化操作需要耗费一些精力。最常见的解决方案包括建立一个由多台机器组成的集群(也称为 farm),或者建立一个多内核机器—一台高性能计算机。
集群
集群是指多台机器为同一目的服务。Azure DevOps 使用集群来管理构建进程,管道为接收到的每个构建请求分配一个 Agent 。实际上,Azure DevOps 管道在构建进程作业的级别上进行并行化处理,在每个 Agent 上运行一个完整的作业,以便可以并行处理多个构建请求。
理论上,如果触发了无限的构建请求流,并且 Agent 得到了充分利用,那么在运行单个构建所需的时间内,可以完成与 Agent 数量相同的 Azure DevOps 作业。虽然这充分利用了构建系统,但利用尽可能多的资源来完成单个构建效果更佳;完成后,将再次分配尽可能多的资源来运行下一个构建,以此类推。
对于更简单的项目,可以通过将一个构建作业分解为多个作业(编译、运行每个测试等)并让原始作业为每个子作业发送新的构建请求,以实现优化。但是,这种方法在同步环境和每个子作业的输出方面会产生非常高的成本。另外,因为这种方法需要在每个参与的 Agent 上设置必要的软件(如果是自托管的),所以并行化工作将受限于用于构建进程的计算机数量。
另外,“手动”并行化工作的复杂且成本较高,因此并不可行。
高性能计算
HPC管理多个单核 Agent 的一种方法是使用一个多核 Agent。这就是高性能计算(HPC)大显身手的地方。HPC(高性能计算机)本质上是一种计算机(物理的或虚拟的),它能够聚合计算能力以提升性能,以此远超单一计算机或者工作站的计算能力。为了实现这一点,HPC 会使用许多 CPU 内核。Windows 机器最多可以支持 256 个内核。
如果在多核 Agent 上运行,构建过程可以很容易地并行运行。例如,如果将需要运行的软件项目(集合)并行化,则可以并行编译尽可能多的集合(不超过可用内核的限制),每个集合可以依次并行编译多个单元。类似地,单元测试也应该互相独立,便于并行。其他测试通常也可以并行化进行。
虽然多核 HPC 可以提高整体性能,但它有两个内在限制:容量和粒度。基于64 位 Windows 的系统(目前)限制为 256 核。对于复杂的多平台软件项目来说,这是一个无法突破的限制。
第二个因素是粒度。如果不花费大量精力修改软件的编译方式,项目集合(或顶级项目)是原子式的,其构建不能分发至多个 Agent 中。
当然,还有第三个因素:价格。HPC 非常昂贵, 也难以适应所有构建相关的进程。
超越集群和 HPC 的限制
有没有一种方法可以将构建过程并行化,且无需花费过多的精力和金钱?是将构建进程分解为离散的工作流,或者购买一台成本较低的机器?我们是否有办法超越工作流或解决方案的粒度限制?
答案是肯定的。Incredibuild 可以并行单个 OS 进程,跨主机集群无缝执行分发的进程,同时顺畅地将远程计算机上的构建 Agent 环境虚拟化。
有了 Incredibuild 独特的虚拟化计算解决方案,构建可以变得高效轻松。Incredibuild 可以将任何 Azure DevOps 构建机器转换为虚拟的超级计算机,并充分利用网络或公共云上远程机器的空闲 CPU 周期。即使这些远程机器处于正在使用状态,也丝毫不受影响。无需更改任何源代码,更不需要额外的硬件。
Incredibuild 可以合并到现有的 Azure DevOps 构建管道中,构建系统(如MSBuild)可以并行数百个编译任务,从而加快构建时间。一旦激活,Incredibuild 会截获构建系统创建的编译进程命令,将其绕道执行,以在另一台机器上远程运行。Incredibuild 独特的虚拟化技术在远程主机上按需模拟构建 Agent 环境,允许编译进程在远程主机上执行。其效果就像在构建 Agent 中运行一样,将编译结果和其他输出发送回 Agent。
需要注意的是,这个过程并不需要进行任何额外安装,也无需将任何资源复制到远程计算机上。Incredibuild 动态模拟远程编译进程所需的一切(包括 dev 堆栈、DLL、可执行文件、源文件等)。
图1:用 Incredibuild 构建谷歌 Chrome 浏览器
在图 1(上图)中,我们可以看到参与构建加速的所有内核(在这个场景中为100 个内核)。构建监视器中的每个水平条表示正在执行的任务。
Minitab 是另一个利用 Incredibuild Cloud 和 Azure DevOps 加速构建进程的案例。Minitab 是一个强大的统计软件,它需要一个解决方案以加快构建,同时将工作进程迁移入云(将 CI 转移到云上)。事实证明,使用 Incredibuild Cloud 和 Azure DevOps 是力量和速度的强强联手,Tony 对此解释道:“Incredibuild 在 100 台机器上同时运行,这对于 Minitab 的开发优化甚为有效。”
这样的案例不胜枚举。事实上,借助 Incredibuild,几乎任何可以并行执行的工作负载都能以相同的方式加速,无论是由 Azure DevOps Agent 激活还是由开发人员的工作站激活。这意味着,Incredibuild 可以有效地将任何一台机器转换成500多个内核的主机,使用网络中已有的闲置资源或按需供给的公共云资源,让耗时的工作负载运行得更快。
今天的企业竞争如逆水行舟,不进则退。速度、敏捷、快速——这些不仅仅是只言片语,更是决定了企业的生死存亡。开发进程中的每一步都需要得到最大限度的检查和优化。这就是为什么一流企业的客户永远不会在速度和质量上妥协。因为他们想要鱼(速度)与熊掌(质量)兼得,而且在效率上要求即刻甚至提前实现。查看构建进程是一个很好的开始。构建进程缓慢是企业发展的大患,需要尽早根治,尤其是已有高效的加速方案,既不影响质量也不会浪费太多资源。