首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >改一行代码等十分钟?CI 构建提速的几个狠招

改一行代码等十分钟?CI 构建提速的几个狠招

原创
作者头像
克劳德2048
发布2026-08-26 14:30:49
发布2026-08-26 14:30:49
1200
举报

摘要

提交一行代码却要等十分钟流水线才跑完,开发节奏被构建拖慢。本文从缓存、并行、按需构建、节点规格几个角度,讲清 CI 构建提速的实操方法,并结合腾讯云云原生构建 CNB 的配置方式给出可直接落地的示例。

一、构建慢,慢在哪里要先看清楚

"改一行代码等十分钟"是很多团队的日常。但构建慢往往不是一个笼统的问题,盲目加机器未必管用,得先定位时间花在了哪。一次典型的 CI 流水线,耗时通常来自几个环节:

a. 拉取代码与依赖:每次从零拉取依赖、安装 node_modules 或下载 Maven 依赖,网络传输和解析都要花时间。

b. 全量编译构建:尤其是大型单体仓库(Monorepo),哪怕只改了一个子模块,也把所有模块从头构建一遍。

c. 串行执行:本可以并行跑的任务被排成一列,一个跑完才轮到下一个。

d. 资源不足排队:构建节点规格偏低或并发上限不够,任务只能排队等待。

定位清楚之后,提速就有了方向:能缓存的缓存下来,能并行的并行起来,能跳过没改的部分就跳过。下面逐个讲。

二、把依赖和产物缓存下来

构建提速里收益最明显的一招,就是构建缓存。绝大多数构建任务都有大量重复劳动——每次安装相同的依赖、每次重新编译没变动的模块。缓存的思路就是把这些中间产物存下来,下次构建时直接复用,而不是从头再来。

缓存主要分两类:

  • 依赖缓存:把 node_modules、Maven 本地仓库、pip 缓存这类依赖目录缓存下来。依赖没变(锁文件没变)时直接命中,省掉下载和解析的时间。
  • 编译产物缓存:把上一次的编译结果、构建中间文件缓存下来。代码只改了局部时,未变动的部分可以跳过编译。

以腾讯云云原生构建(Cloud Native Build,简称 CNB)为例,它原生支持构建缓存,可以在声明式配置里开启,加速重复构建的执行速度。需要说明的是,缓存是通过 Pipeline 级别的 docker.volumes 声明的(而非 Job 内单独配置),声明后供这条流水线里的各个 Stage / Job 共同复用,让"安装依赖""编译"这些高频阶段优先命中缓存。

下面是一个示意性的 .cnb.yml 片段,展示如何在流水线中声明缓存目录(字段写法以官方语法手册为准):

代码语言:yaml
复制
# .cnb.yml 示意示例:通过 docker.volumes 声明依赖缓存
main:
  push:
    - docker:
        image: node:20
        volumes:
          - /root/.npm        # 缓存 npm 依赖
          - ./node_modules    # 缓存 node_modules,命中时跳过重复下载
      stages:
        - name: install
          jobs:
            - name: install-deps
              image: node:20
              script: npm ci
        - name: build
          jobs:
            - name: compile
              image: node:20
              script: npm run build

第一次构建时缓存为空,依赖照常下载安装;之后只要锁文件没变,node_modules 直接从缓存恢复,安装阶段的时间就能大幅缩短。对于每天要跑几十上百次构建的团队,缓存带来的累积收益相当可观。

三、把能并行的任务拆开来跑

很多流水线慢,不是因为单个任务慢,而是任务之间在"排队"。CNB 的流水线结构天然支持并行:

  • Stage 内并行:同一个 Stage 内的多个 Job 会并行执行。也就是说,"单元测试"和"代码检查"这类互不依赖的任务,放在同一个 Stage 里就能同时跑,而不是一个等一个。
  • 多分支并行:配合多种触发规则,不同分支的推送可以各自独立触发流水线,互不阻塞。

要利用好并行,关键是理清任务之间的依赖关系:没有依赖的任务尽量放进同一个 Stage 并行;有依赖的(比如"构建"必须在"测试"之前)才拆到相邻 Stage 串行。这样能把原本串成一条线的时间,压缩成几条线并排跑的时间。

四、Monorepo 按需构建,只跑改动的部分

单体仓库(Monorepo)是构建提速里最需要针对性优化的场景。Monorepo 把多个模块、多个服务放在同一个仓库,好处是原子化提交、统一依赖管理,但副作用是"牵一发动全身"——改了一个子模块,传统流水线却把所有模块全部重新构建和测试一遍,大量算力浪费在没变动的代码上。

按需构建(也叫受影响范围构建)是解决这个问题的关键:流水线先分析这次提交到底改了哪些模块,只构建和测试真正被影响的模块及其依赖,其余的跳过。

CNB 提供了 Monorepo 按需构建的实践方案,结合它的触发规则和分支 glob 匹配,可以做到"改了哪个模块,就只构建哪个模块"。再配合前文讲的缓存,未变动模块连编译都省了,构建时间自然从"整个仓库的规模"降到"改动模块的规模"。对于模块众多的前端、后端大仓,这一招往往能把十分钟的构建压到一两分钟。

五、按任务规模选择合适的构建节点

缓存、并行、按需构建都做完,如果构建节点本身规格偏低,单任务还是会跑得慢。CNB 提供多种规格的构建节点,可按任务规模按需声明:

节点架构

CPU 规格

适用场景

amd64

1~64 核

通用构建,可放大核数缩短编译时间

arm64 / v8

1~16 核

ARM 架构的构建与验证

GPU

固定 16 核 + 48GB 显存

AI 训练、图形渲染等重算力任务

提速的实用搭配是:常规构建用中等规格节点 + 缓存,性价比最高;全量构建或大型编译任务临时放大核数,用并行度换时间;AI / 图形相关任务再用 GPU 节点。所有节点最大构建时长为 18 小时,常规构建完全够用。

需要提醒的是,规格越高单位时间消耗的资源也越多。社区版的计费按实际核时统计,云原生构建-CPU 免费额度为 160 核时/月,超额按 0.125 元/核时计费;云原生构建-GPU 无免费额度,按 0.5 元/核时计费。提速的同时留意用量,避免不必要的资源浪费。

六、几个容易忽略的细节

a. 选离得近的构建镜像:每个 Job 在指定 Docker 镜像中运行,优先用官方预置的常用语言镜像,减少镜像拉取和初始化开销。

b. 让缓存键稳定:缓存能否命中,取决于依赖锁文件是否稳定。不要用会频繁变动的内容做缓存键,否则每次都是"未命中",缓存形同虚设。

c. 及时跳过没必要的阶段:比如只改了文档却触发全量测试,可以在触发规则里做路径过滤,让文档变更根本不拉起构建流水线。

d. 关注实际运行时长:构建完成后按实际运行时间统计用量,跨月执行的任务会计入结束时间所在的自然月,安排长任务时留意这一点。

七、小结

构建提速没有一招通用的银弹,得先定位时间花在哪,再对症下药:依赖和产物用缓存复用,无依赖的任务并行跑,Monorepo 只构建改动的模块,再按任务规模选配合适的节点规格。这几招组合起来,通常能把"改一行等十分钟"压缩到可接受的范围。

腾讯云 CNB 的构建缓存、Pipeline/Stage/Job 并行结构、Monorepo 按需构建实践,以及 1~64 核 amd64、1~16 核 arm64、GPU 等多规格构建节点,正好覆盖了从缓存到算力的提速环节。如果你正被漫长的构建等待拖累,不妨从缓存和按需构建这两招开始试起。

想把这些提速手段落到自己的项目里,可以到腾讯云 CNB 给流水线加上 volumes 缓存、按 Monorepo 配按需构建,先跑通缓存命中,再按构建时长逐步调优节点规格。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 摘要:
  • 一、构建慢,慢在哪里要先看清楚
  • 二、把依赖和产物缓存下来
  • 三、把能并行的任务拆开来跑
  • 四、Monorepo 按需构建,只跑改动的部分
  • 五、按任务规模选择合适的构建节点
  • 六、几个容易忽略的细节
  • 七、小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档