CI流水线从18分钟降到2分半,我只改了这5个地方(不是换工具)

🔑 关键词:持续集成,CI优化,Jenkins,GitHub Actions,构建缓存

📖 摘要:一个30人团队的真实CI优化记录,包含具体参数、成本对比和踩坑细节。不推荐工具,只讲思路。

先交代背景

图片

我们团队30人,后端Node.js,前端React,用的Jenkins 2.346.1,跑在AWS c5.xlarge(4核8G)上。去年年初CI平均2分钟,到了今年3月变成了18分钟。每次提交等18分钟才能知道有没有挂,开发同学都快疯了。我作为DevOps,每天被催。说实话,我当时第一反应是换GitHub Actions,因为大家都说它快。结果一算账,我沉默了。

算账:换工具还是优化?

图片

我们每月大概3000次构建,每次18分钟,总共54000分钟。GitHub Actions免费额度2000分钟/月,超出部分$0.008/分钟。54000-2000=52000分钟,乘以0.008等于$416。加上存储和流量,每月至少$450。而我们的Jenkins服务器c5.xlarge按需$0.17/小时,每月$124,加100G EBS $10,流量$5,总共$140。如果优化到2分半,总时间7500分钟,GitHub Actions也在免费额度内,但迁移成本呢?重写所有pipeline,至少两周。所以我决定先优化Jenkins,看看能到什么程度。

第一步:找出耗时大头

图片

我用Jenkins的Timestamper插件打了时间戳,又装了Build Time Trend。结果很清晰:npm install 7分钟,单元测试+集成测试8分钟,构建3分钟。我靠,npm install居然要7分钟?因为我们没缓存node_modules。每次都是全新clone然后npm install。这里有个坑:缓存node_modules容易导致依赖不一致,所以我们用了npm ci加上缓存~/.npm目录。具体配置:在Jenkinsfile里加cache(path: '~/.npm', key: "${env.BRANCH_NAME}-${hashFiles('package-lock.json')}")。改完后npm install从7分钟降到40秒。但注意,第一次构建还是会慢,后面就快了。

第二步:测试分层,只跑相关的

图片

测试占了8分钟,其中单元测试5分钟,集成测试2分钟,E2E 1分钟。我们用了Jest 27,本来可以并行,但之前没开。开了--maxWorkers=4,单元测试降到2分钟。但这还不够。我发现很多测试跟当前改动完全无关。比如改了一个React组件,却跑了所有后端API测试。于是我写了个脚本:用git diff --name-only HEAD~1获取变更文件,然后映射到测试文件。对于Jest,直接用jest --findRelatedTests $(git diff --name-only HEAD~1)。这样只跑相关测试,单元测试时间从2分钟降到40秒。集成测试同理,用--testPathPattern匹配。E2E只跑冒烟,从1分钟降到20秒。这里有个坑:如果改动了公共库,映射可能不准,所以每周五跑一次全量测试。千万别省这个。

图片

第三步:并行与构建缓存

单元测试我们用jest --shard=1/4分成4个并行任务,但注意你的CI机器得扛得住。我们4核,开4个worker刚好。构建部分用了Docker BuildKit,把package.json和package-lock.json的COPY层放在前面,这样依赖层能缓存。Dockerfile里写:COPY package*.json ./然后RUN npm ci --only=production,再COPY . .。这样代码改动不会影响依赖层,构建从3分钟降到20秒。另外,Jenkins的agent我们用了Docker插件,每个stage起一个容器,避免环境污染。

图片

结果与反思

优化后总时间:npm install 30秒 + 单元测试80秒 + 集成测试20秒 + 构建20秒 = 2分30秒。每月总构建时间从54000分钟降到7500分钟。如果换GitHub Actions,现在只需$44/月,但我们的Jenkins成本还是$140/月,因为服务器一直开着。不过开发者等待时间从18分钟降到2分半,这个价值远大于$100差价。我最后的观点:CI优化的核心不是换工具,也不是堆机器,而是“按需计算”。大多数团队把CI当成了全量回归,每次提交都跑所有测试。其实应该像Monorepo那样,只跑受影响的。我们借鉴了Nx的affected逻辑,但自己写脚本实现。另外,别迷信并行,flaky test会让你更痛苦。我们曾经开8个并行,结果flaky率从2%涨到15%,后来降到4个才稳定。所以,先优化测试质量,再谈速度。

🏷️ 标签: