分布式任务执行 (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 系统中创建两种不同类型的作业。
- 一个控制要执行内容的主作业
- 多个实际执行任务的代理作业
主作业执行流程如下所示
# Coordinate the agents to run the tasks
- npx nx-cloud start-ci-run
# Run any commands you want here
- lerna run lint --since=main & lerna run test --since=main & lerna run build --since=main
# Stop any run away agents
- npx nx-cloud stop-all-agents
代理作业执行流程非常简单
# Wait for tasks to execute
- 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 中配置它们的更多信息。
请注意,只有可缓存的操作才能进行分发,因为它们必须在主作业上重放。