3. CI/CD 流水线基础:Jenkins/GitLab CI 核心概念、Pipeline 即代码、Stage 与 Job 定义
在多租户 SaaS 鉴权拦截链路中,每一次代码提交都可能影响租户隔离、Token 校验或拦截规则。为了在每次变更后自动验证这些关键路径,必须建立标准化的 CI/CD 流水线。本章聚焦 Jenkins 与 GitLab CI 的核心概念,重点讲解 Pipeline 即代码的实现方式,以及 Stage 与 Job 的定义规则。
3.1 CI/CD 流水线核心概念
CI/CD 流水线将代码从提交到部署的过程拆解为多个自动化阶段。在多租户 SaaS 项目中,流水线需要额外处理租户上下文、多环境配置以及鉴权拦截的专项测试。
| 概念 | 说明 | 多租户 SaaS 场景要点 |
|---|---|---|
| 持续集成 (CI) | 代码合并后自动构建、静态分析、单元测试 | 需注入不同租户的测试 Token,验证隔离性 |
| 持续交付 (CD) | 通过自动化测试后,自动部署到预发布环境 | 预发布环境需模拟多租户数据源与拦截规则 |
| Pipeline | 定义整个自动化流程的配置文件 | Pipeline 即代码,与鉴权测试脚本一同版本管理 |
| Stage | 流水线中的逻辑阶段,如构建、测试、部署 | 鉴权拦截测试应作为独立 Stage,避免阻塞其他流程 |
| Job | Stage 内的具体执行任务,可并行或串行 | 不同租户的鉴权测试可拆分为多个并行 Job |
实践建议: 在多租户 SaaS 项目中,建议将“鉴权拦截测试”定义为流水线中的 门禁 Stage。只有该 Stage 全部 Job 通过,才允许合并到主分支或触发后续部署。
3.2 Pipeline 即代码 (Pipeline as Code)
Pipeline 即代码将流水线配置以文本文件形式存储在代码仓库中,与源代码一同进行版本控制、代码审查和分支管理。这种方式保证了流水线的可追溯性和可重复性。
3.2.1 Jenkins Pipeline 即代码
Jenkins 支持两种 Pipeline 语法:声明式 (Declarative) 和 脚本式 (Scripted)。声明式语法结构清晰,适合大多数 SaaS 项目;脚本式更灵活,适合复杂定制场景。
// Jenkinsfile - 声明式 Pipeline 示例
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build & Unit Test') {
steps {
sh 'mvn clean compile'
sh 'mvn test'
}
}
stage('Multi-Tenant Auth Intercept Test') {
parallel {
stage('Tenant-A') {
steps {
sh 'mvn test -Dtest=AuthInterceptTest -Dtenant.id=tenant-a'
}
}
stage('Tenant-B') {
steps {
sh 'mvn test -Dtest=AuthInterceptTest -Dtenant.id=tenant-b'
}
}
stage('Tenant-C') {
steps {
sh 'mvn test -Dtest=AuthInterceptTest -Dtenant.id=tenant-c'
}
}
}
}
stage('Deploy to Staging') {
steps {
sh 'kubectl apply -f k8s/staging/'
}
}
}
post {
failure {
emailext (
subject: "Pipeline Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
body: "鉴权拦截测试失败,请检查日志。",
to: "team@saas.com"
)
}
}
}
3.2.2 GitLab CI 即代码
GitLab CI 使用 .gitlab-ci.yml 文件定义流水线。其核心概念包括 stages、jobs、runner 和 artifacts。GitLab CI 天然支持并行 Job 和依赖传递。
# .gitlab-ci.yml - 多租户鉴权测试流水线
stages:
- build
- unit_test
- auth_intercept_test
- deploy_staging
variables:
MAVEN_OPTS: "-Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
build_job:
stage: build
script:
- mvn clean compile
artifacts:
paths:
- target/
unit_test_job:
stage: unit_test
script:
- mvn test
dependencies:
- build_job
auth_intercept_test:
stage: auth_intercept_test
parallel:
matrix:
- TENANT_ID: ["tenant-a", "tenant-b", "tenant-c"]
script:
- mvn test -Dtest=AuthInterceptTest -Dtenant.id=$TENANT_ID
artifacts:
when: always
reports:
junit: target/surefire-reports/TEST-*.xml
deploy_staging_job:
stage: deploy_staging
script:
- kubectl apply -f k8s/staging/
only:
- main
dependencies:
- auth_intercept_test
关键差异对比:
- Jenkins:Pipeline 文件名为 Jenkinsfile,语法更丰富,支持复杂的脚本逻辑和共享库。
- GitLab CI:配置文件为 .gitlab-ci.yml,语法简洁,与 GitLab 平台深度集成,天然支持矩阵并行测试。
- 共同点:都支持 Stage 串行、Job 并行、环境变量注入、制品传递和失败通知。
3.3 Stage 与 Job 定义规则
Stage 和 Job 是流水线的核心构建块。合理的 Stage 划分和 Job 定义直接影响流水线的执行效率与可维护性。
3.3.1 Stage 定义原则
- 逻辑独立:每个 Stage 完成一个独立的功能阶段,如构建、单元测试、鉴权测试、部署。
- 串行依赖:Stage 之间默认串行执行,后一个 Stage 依赖前一个 Stage 的成功状态。
- 门禁设置:将关键验证(如鉴权拦截测试)设为门禁 Stage,失败即阻断后续流程。
- 最小化粒度:避免 Stage 过多导致流水线过长,通常 4~6 个 Stage 即可覆盖 SaaS 项目的核心流程。
3.3.2 Job 定义原则
- 单一职责:每个 Job 只做一件事,如“运行租户 A 的鉴权测试”或“构建 Docker 镜像”。
- 并行执行:同一 Stage 内的 Job 可以并行执行,适合多租户并发测试场景。
- 资源标签:为 Job 指定运行环境标签(如
agent { label 'docker' }),确保测试环境一致性。 - 超时与重试:为 Job 设置超时时间(如
timeout 10)和重试策略(如retry 2),避免流水线卡死。
常见陷阱:
- 将多个租户的鉴权测试写在同一个 Job 中,导致失败时无法快速定位是哪个租户的问题。
- Stage 划分过细(如将编译和打包拆成两个 Stage),增加流水线总耗时且无实际收益。
- 忽略 Job 之间的资源竞争,例如多个并行 Job 同时写入同一个数据库或文件。
3.4 多租户鉴权测试流水线架构图
下图展示了针对多租户 SaaS 鉴权拦截链路的 CI/CD 流水线架构。流水线从代码提交触发,经过构建、单元测试、多租户并行鉴权测试,最终部署到预发布环境。
3.5 多租户并行测试 Job 执行流程
下图展示了鉴权拦截测试 Stage 内部,多个租户 Job 的并行执行流程。每个 Job 独立运行,互不干扰,最终汇总测试报告。
3.6 最佳实践总结
| 实践项 | 说明 | 推荐工具/方法 |
|---|---|---|
| Pipeline 即代码 | 流水线配置与源代码一同版本管理 | Jenkinsfile / .gitlab-ci.yml |
| 门禁 Stage | 鉴权拦截测试作为强制门禁 | Stage 失败阻断后续流程 |
| 并行 Job | 不同租户的测试并行执行 | Jenkins parallel / GitLab CI parallel:matrix |
| 环境隔离 | 每个 Job 使用独立的测试环境或数据 | Docker 容器 / Kubernetes Pod |
| 失败通知 | 门禁失败时及时通知团队 | 邮件 / 钉钉 / Slack Webhook |
| 测试报告 | 收集并展示测试结果,便于追溯 | JUnit 报告 / Allure 报告 |
核心要点:
- Pipeline 即代码是 CI/CD 现代化的基础,确保流水线可追溯、可复用。
- Stage 定义逻辑阶段,Job 定义具体任务;Stage 串行,Job 可并行。
- 多租户鉴权测试应作为门禁 Stage,利用并行 Job 提升测试效率。
- Jenkins 和 GitLab CI 都支持 Pipeline 即代码,选择取决于团队技术栈和平台偏好。