分发任务执行(DTE)
Lerna 通过缓存和 --since
标志加速了您的平均 CI 时间。但这些特性都无法帮助解决最坏的情况。当仓库核心发生修改,并且每个任务都需要在 CI 中运行时,提高性能的唯一方法是添加更多代理作业并有效地并行任务。
并行任务最明显的方法是按类型拆分任务:在一个作业上运行所有测试,在另一个作业上运行所有构建,在第三个作业上运行所有 lint 任务。这种策略称为分箱。如果某些测试任务有构建任务作为先决条件,这可能会变得困难,但假设您找到了处理这种情况的方法,典型的设置可以如下图所示。在这里,测试任务会延迟到所有必要的构建工件准备就绪,但构建和 lint 任务可以立即开始。
分箱方法的问题是,您最终会在一个或多个作业上出现空闲时间。Nx 的分布式任务执行通过根据任务的平均运行时间将每个单独的任务分配给代理作业,将这种空闲时间减少到最小。Nx 还保证任务以正确的顺序执行,并使用分布式缓存确保之前任务的构建工件在每个需要它们的代理作业上都存在。
当您设置 Nx 的分布式任务执行时,您的任务图将更像这样:
不仅 CI 会更快完成,而且调试体验与在单个作业上运行所有 CI 时完全相同。这是因为 Nx 使用分布式缓存在主作业上重新创建所有日志和构建工件。
在这个详细指南中了解更多关于改善最坏情况下 CI 时间的信息。
设置
要分发任务执行,您需要(1)连接到 Nx Cloud 和(2)在 CI 工作流中启用 DTE。每个步骤都可以通过单个命令启用:
nx connect-to-nx-cloud
nx generate @nrwl/workspace:ci-workflow --ci=github
--ci
标志可以是 github
、circleci
或 azure
。有关设置 DTE 的更多详细信息,请阅读此指南。
CI 执行流程
分布式任务执行可以在任何 CI 提供商上工作。您负责在 CI 系统中启动作业。Nx Cloud 然后协调这些作业的协同工作。您需要在 CI 系统中创建两种不同类型的作业。
- 一个控制将要执行内容的主作业
- 多个实际执行任务的代理作业
主作业执行流程如下:
# 协调代理运行任务
- npx nx-cloud start-ci-run
# 在这里运行您想要的任何命令
- lerna run lint --since=main & lerna run test --since=main & lerna run build --since=main
# 停止所有失控的代理
- npx nx-cloud stop-all-agents
代理作业执行流程非常简单:
# 等待执行任务
- npx nx-cloud start-agent
主作业看起来或多或少与您没有使用任何分发时相同。您唯一需要做的就是在开始时调用 npx nx-cloud start-ci-run
,并在最后可选地调用 npx nx-cloud stop-all-agents
。
代理作业运行长时间运行的 start-agent
进程,执行与给定 CI 运行相关的所有任务。设置它们唯一需要做的就是调用 npx nx-cloud start-agent
。这个进程将继续运行,直到 Nx Cloud 告诉它终止。
注意,主作业和代理作业必须具有相同的环境和相同的源代码。它们大约在同一时间开始。一旦主作业完成,所有代理将被停止。
还需要注意的是,Nx Cloud 代理不是机器,而是在机器上运行的长时间运行的进程。即,Nx Cloud 不管理您的代理 - 您需要在 CI 配置中执行此操作(请查看下面的 CI 示例)。
Nx Cloud 是一个编排器。主作业告诉 Nx Cloud 要运行什么,Nx Cloud 将这些任务分布在代理上。Nx Cloud 将自动将文件从一个代理移动到另一个代理,从代理移动到主作业。
最终结果是,当 lerna run build --since=main
在主作业上完成时,代理上创建的所有文件工件都会被复制到主作业,就像主作业本地构建了所有内容一样。
并行运行
--concurrency
会传播到代理。例如,npx lerna run build --since=main --concurrency=3 --dte
告诉 Nx Cloud 在每个代理上并行运行最多 3 个构建目标。因此,如果您有 10 个代理,您将在所有代理上并行运行最多 30 个构建。
您还希望尽可能并行运行尽可能多的命令。例如,
- lerna run lint --since=main
- lerna run test --since=main
- lerna run build --since=main
比
- lerna run lint --since=main & lerna run test --since=main & lerna run build --since=main
更糟。后者将同时调度所有三个命令,因此如果一个代理找不到要构建的内容,它将开始运行测试和 lint。结果是更好的代理利用率和更短的 CI 时间。
CI/CD 示例
下面的示例展示了如何使用 Nx 和 Nx Cloud 设置 CI,使用分布式任务执行和分布式缓存。
每个组织管理 CI/CD 管道的方式都不同,因此示例不涵盖 CI/CD 的特定于组织的方面(例如,部署)。它们主要关注正确配置 Nx。
请阅读以下指南,了解如何在 CI 中配置它们:
请注意,只有可缓存的操作可以被分发,因为它们必须在主作业上重放。