GitLab CI 核心概念拆解:Stages 与 Jobs 到底有什么本质区别?
GitLab CI 核心概念拆解Stages 与 Jobs 到底有什么本质区别 Stages 与 Jobs 关系流程图一、核心定义Stage 是章节Job 是段落二、配置实战从零编写 .gitlab-ci.yml 对比演示第一步全局声明 Stages第二步编写具体的 Jobs三、执行逻辑流水线运行时的时间线推演时间点 T0流水线启动时间点 T1Build 阶段时间点 T2Test 阶段时间点 T3Security 阶段时间点 T4Deploy 阶段四、五大核心区别别再混淆了五、进阶技巧needs 关键词打破串行限制六、常见错误与排查清单错误1Job写了但没执行错误2想并行但实际串行错误3前一阶段失败后面全停 可视化总结图 总结The Begin点点关注收藏不迷路⬇ ⬇ 底部 ⬇ ⬇很多刚接触GitLab CI的开发者都会被.gitlab-ci.yml中的stages和jobs搞晕——它们看起来都像是一组要执行的任务。但二者在流水线中扮演着**截然不同**的角色混淆它们会导致流水线执行顺序混乱、效率低下。 Stages 与 Jobs 关系流程图先通过一张图直观理解二者在流水线中的层级关系Pipeline流水线Stage内部_并行执行属于属于属于⚙️ Job: build-frontend编译前端代码 Stage: build 构建阶段 Stage: test 测试阶段 Stage: deploy 部署阶段⚙️ Job: build-backend编译后端代码⚙️ Job: build-docs生成API文档关键解读Stage阶段是横向的时间轴控制执行顺序。Job作业是纵向的执行单元同一Stage内的Jobs可并行跑。一、核心定义Stage 是章节Job 是段落理解二者本质一个比喻就够了把.gitlab-ci.yml看作一本书。Stages是书的章节目录第一章、第二章…规定阅读的先后顺序。Jobs是每章中的具体段落第一章第一节、第一章第二节…同一章内的多个段落可以同时阅读。在技术实现上维度Stage阶段Job作业职责定义流水线的执行顺序和逻辑边界定义具体要执行的任务数量一条流水线可有多个Stage一个Stage可包含多个Job执行关系串行执行前一个Stage全部完成后才进入下一个同一Stage内并行执行无依赖关系时配置位置顶层stages:关键字全局声明以独立条目定义通过stage:字段归属环境载体不直接执行命令只做容器拥有独立的Runner、环境变量、镜像二、配置实战从零编写 .gitlab-ci.yml 对比演示让我们通过一个前后端分离项目的配置直观感受二者的协作。第一步全局声明 Stages在文件顶部用stages关键字定义流水线的阶段顺序# 全局阶段定义 stages:-build# 阶段1编译-test# 阶段2测试-security# 阶段3安全扫描-deploy# 阶段4部署关键规则Stages列表的顺序决定了执行顺序。如果某个Job指定的Stage不在这个列表中该Job会被静默忽略。如果不显式定义stagesGitLab默认使用.pre → build → test → deploy → .post五个阶段。第二步编写具体的 Jobs每个Job是一个顶级的YAML键名通过stage:字段归属到上面定义的某个阶段。# 阶段1Build 构建 build-frontend:stage:build# font colorgreen归属到 build 阶段/fontimage:node:18-alpinescript:-cd frontend-npm install-npm run buildartifacts:paths:-frontend/dist/build-backend:stage:build# font colorgreen同样归属 build 阶段与上面并行执行/fontimage:maven:3.8-openjdk-11script:-cd backend-mvn clean package-DskipTestsartifacts:paths:-backend/target/*.jar# 阶段2Test 测试 unit-test-frontend:stage:test# font colorgreen必须等 build 阶段全部完成才执行/fontimage:node:18-alpinescript:-cd frontend-npm testunit-test-backend:stage:testimage:maven:3.8-openjdk-11script:-cd backend-mvn test# 阶段3Security 安全扫描 sast-scan:stage:securityscript:-echo Running SAST analysis...# 阶段4Deploy 部署 deploy-to-staging:stage:deployscript:-echo Deploying to staging server...environment:name:stagingonly:-develop三、执行逻辑流水线运行时的时间线推演当你git push触发上述配置后GitLab Runner的实际行为如下时间点 T0流水线启动Runner 解析.gitlab-ci.yml构建DAG有向无环图。时间点 T1Build 阶段并行启动build-frontend和build-backend两个Job。它们运行在不同的容器中互不干扰。只有当两个Job都成功流水线才会进入下一阶段。如果有一个失败整个Build阶段标记为失败后续所有阶段停止执行。时间点 T2Test 阶段Build阶段成功后并行启动unit-test-frontend和unit-test-backend。它们可以下载artifacts中保存的构建产物进行测试。时间点 T3Security 阶段只有一个Jobsast-scan它单独运行。时间点 T4Deploy 阶段deploy-to-staging执行仅在develop分支触发。四、五大核心区别别再混淆了为了让你彻底记住这里用表格总结最关键的差异点对比维度StageJob1. 物理形态逻辑概念不占Runner资源实际进程占用Runner执行器2. 执行顺序串行前一个Stage全部Job完成后才进入下一个并行同Stage内无依赖的Job同时启动3. 镜像与环境不能定义镜像每个Job可以指定独立的image4. 失败影响一个Stage中任意Job失败整个Stage失败一个Job失败不影响同Stage其他Job默认5. 脚本执行不直接执行script通过script字段定义具体命令五、进阶技巧needs 关键词打破串行限制GitLab 10.x 引入了needs关键字允许Job跨Stage依赖打破严格的串行限制。stages:-build-test-deploybuild-backend:stage:buildscript:-mvn package# 传统模式必须等整个build阶段完成# 新模式通过 needs 指定只等 build-backenddeploy-backend:stage:deploy# 它属于 deploy 阶段needs:[build-backend]# 但只需要 build-backend 完成即可执行script:-echo 后端单独部署执行效果deploy-backend不再等待build-frontend或其他Build Job。只要build-backend完成它就会立刻启动即使其他Build Job还在运行。这大幅缩短了整体流水线时间。六、常见错误与排查清单错误1Job写了但没执行排查检查Job的stage:值是否在全局stages:列表中。大小写必须完全一致。# 错误示例stages:-buildmy-job:stage:Build# ❌ 大小写不匹配Job被忽略错误2想并行但实际串行排查两个Job是否写了不同的stage值。只有同Stage的Job才会并行。# 错误示例想并行但分到了两个Stagejob-a:stage:test1# 串行job-b:stage:test2# 串行# 正确示例真正并行job-a:stage:testjob-b:stage:test错误3前一阶段失败后面全停解决方案使用allow_failure: true让不关键的Job失败不阻断后续。lint-check:stage:testscript:npm run lintallow_failure:true# lint失败不影响后续部署 可视化总结图执行顺序概念层级并行并行串行等待串行等待Pipeline流水线Stage: build构建阶段Stage: test测试阶段Stage: deploy部署阶段Job: build-frontendJob: build-backendJob: unit-testJob: integration-testJob: deploy-prod 总结通过本文你应当深刻理解Stage 是时间维度的编排定义流水线的阶段顺序控制什么时候做。Job 是空间维度的执行定义具体的任务内容控制做什么。同一Stage的Jobs并行执行不同Stage之间严格串行。needs 关键字可以打破Stage限制实现DAG式灵活编排。掌握这对核心概念你就能设计出高效、清晰、可维护的GitLab CI流水线The End点点关注收藏不迷路⬆ ⬆ 顶部 ⬆ ⬆