【CI/CD·入门篇】核心概念全解:构建、测试、集成、交付、部署与回滚

发布时间:2026/8/3 15:32:07
【CI/CD·入门篇】核心概念全解:构建、测试、集成、交付、部署与回滚 前言上一篇我们了解了 CI/CD 的整体面貌但构建测试部署这些词看似简单实际操作中有很多细节和坑。本篇逐一拆解流水线中的核心概念让你在后续搭建流水线时清楚知道每个阶段在做什么、为什么要做、怎么做。一、构建Build从源码到产物什么是构建构建是将人类可读的源代码转化为机器可执行的产物的过程。不同语言栈的构建方式不同| 语言/框架 | 构建工具 | 产物类型 | 示例命令 ||-----------|---------|---------|---------|| Java | Maven / Gradle | JAR / WAR |mvn clean package|| Go | go build | 二进制文件 |go build -o app .|| Node.js | npm / yarn / pnpm | dist 目录 |npm run build|| Python | pip / poetry | wheel / egg |python setup.py bdist_wheel|| 前端 | webpack / vite | 静态文件 |npm run build|构建阶段的关键实践1. 确定性构建同一个代码版本不管在谁的机器上构建结果应该一致。实现方式# 固定基础镜像版本 FROM node:18.19.0-alpine AS builder WORKDIR /app # 先复制 lock 文件利用 Docker 缓存层 COPY package-lock.json ./ RUN npm ci # ci 模式严格按 lock 文件安装不用 package.json COPY . . RUN npm run build**踩坑提示**用 npm install 而非 npm ci 会导致不同时间构建出不同的依赖版本。CI 环境必须用 npm ci或 yarn install --frozen-lockfile。2. 构建缓存大型项目全量构建可能需要10-20分钟。利用缓存可以大幅提速# GitLab CI 缓存示例 build: cache: key: ${CI_COMMIT_REF_SLUG} paths: - .m2/repository # Maven 本地仓库 - node_modules/ # Node 依赖 script: - mvn clean package -DskipTests3. 构建产物的版本管理每次构建出的产物应该有一个唯一标识通常用 Git commit hash 构建时间VERSION$(git rev-parse --short HEAD)-$(date %Y%m%d%H%M) docker build -t myapp:${VERSION} .二、测试Test流水线的守门员测试金字塔/\ / \ E2E 测试少量 /----\ 速度慢、成本高、维护难 / \ / 集成 \ 集成测试适量 / 测试 \ 验证模块间交互 /------------\ / \ / 单元测试大量\ 速度快、覆盖率高 -------------------- CI 中跑得最多的CI 中的测试策略| 测试类型 | CI 中执行 | 说明 ||---------|----------|------|| 单元测试 | 每次提交 | 必须跑覆盖率应 70% || 集成测试 | 每次提交/每日 | 模块间接口验证 || E2E 测试 | 每日/发版前 | 全链路验证慢但重要 || 性能测试 | 每周/发版前 | 基线性能对比 || 安全测试 | 每次提交 | SAST/DAST 扫描 |测试报告与质量门禁CI 流水线不仅要跑测试还要对结果做决策——这就是质量门禁Quality Gate# GitHub Actions 示例测试覆盖率低于 70% 则失败 - name: Run tests with coverage run: mvn test - name: Check coverage run: | COVERAGE$(grep -oP line-rate\K[0-9.] target/site/jacoco/jacoco.xml) echo Coverage: ${COVERAGE} # 转换为百分比 PERCENT$(awk BEGIN {print ${COVERAGE} * 100}) if [ $(awk BEGIN {print ($PERCENT 70)}) -eq 1 ]; then echo Coverage ${PERCENT}% is below 70% threshold exit 1 fi**培训要点**不要一上来就设90%覆盖率门禁这会逼着团队写无意义的测试来凑数。从50%开始逐步提高每季度提升5-10个百分点。三、集成Integration代码合并的艺术持续集成的核心集成不是把代码打包那么简单它的核心是让多人协作的代码尽早、频繁地合并。常见的分支策略与集成方式1. Git Flow适合发版周期长的项目master ──────────●──────────────●──── (生产) \ / / \ / / develop ──●───●────●───●──●──●──── (开发主干) \ / feature ●───●──●─● (功能分支)2. GitHub Flow适合持续部署的项目master ──●──●──●──●──●──●──●── (直接就是生产) \ │ │ / PR ──●──┘ │ └──● │ PR ──────●3. Trunk-Based Development最适合 CI/CDmain ──●──●──●──●──●──●──●──●──●── (所有人频繁合并到 main) \ / \ /\ / short ●─● ●─● ●─● (短生命周期分支1天)**踩坑提示**功能分支存活时间越长合并冲突越大。Trunk-Based Development 要求分支生命周期不超过24小时这对测试自动化要求很高但收益最大。集成触发机制# GitLab CIPR 合并到主干时触发完整流水线 workflow: rules: - if: $CI_PIPELINE_SOURCE merge_request_event when: always - if: $CI_COMMIT_BRANCH main when: always - when: never # 其他情况不触发四、交付与部署Delivery Deployment从代码到线上持续交付 vs 持续部署持续交付Continuous Delivery: 代码 → CI → 测试通过 → 可发布状态 → [人工点击] → 生产环境 持续部署Continuous Deployment: 代码 → CI → 测试通过 → 自动部署 → 生产环境部署策略| 策略 | 原理 | 适用场景 ||------|------|---------|| 滚动部署Rolling | 逐步替换旧实例 | 无状态服务 || 蓝绿部署Blue-Green | 两套环境切换 | 需要快速回滚 || 金丝雀发布Canary | 少量流量先试新版本 | 风险较高的变更 || 影子部署Shadow | 新版本接收流量但不处理 | 性能验证 |部署配置示例Kubernetes 滚动更新apiVersion: apps/v1 kind: Deployment metadata: name: myapp spec: replicas: 4 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # 滚动过程中最多多出1个Pod maxUnavailable: 0 # 滚动过程中不允许减少可用Pod template: spec: containers: - name: app image: myapp:v2 readinessProbe: # 就绪探针只有健康检查通过才接收流量 httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 5**踩坑提示**maxUnavailable: 0 readinessProbe 是零停机部署的关键组合。如果缺少就绪探针Kubernetes 会把流量打到还没启动完的 Pod 上导致用户看到 502。五、回滚Rollback出问题后的救命稻草回滚的两种方式1. 重新部署旧版本推荐# 重新部署上一个版本 kubectl rollout undo deployment/myapp # 回滚到指定版本 kubectl rollout undo deployment/myapp --to-revision3 # 查看部署历史 kubectl rollout history deployment/myapp2. 蓝绿切换瞬间回滚# 当前流量在蓝色环境出问题后瞬间切回绿色 kubectl patch service myapp -p {spec:{selector:{version:green}}}数据库变更的回滚难题代码可以一键回滚但数据库变更DDL往往不可逆-- 正向迁移 ALTER TABLE orders ADD COLUMN status VARCHAR(20); -- 回滚迁移需要提前写好 ALTER TABLE orders DROP COLUMN status;**踩坑提示**数据库迁移必须遵循扩展-收缩Expand-Contract模式。先加新列兼容旧代码部署新代码验证无误后再删旧列。千万不要一步到位改表结构。六、本篇要点回顾1.构建要确定性——同一份代码每次构建结果一致2.测试遵循金字塔——大量单元测试 适量集成测试 少量E2E3.集成要频繁——分支生命周期越短越好4.部署要选对策略——无状态用滚动高风险用金丝雀5.回滚要提前准备——尤其是数据库变更用扩展-收缩模式下一篇预告《CI vs CD vs Continuous Deployment三个层次的区别与联系》——我们用三个实际的流水线配置来展示三个层次的具体差异。