CI/CD 流水线
概述
手工部署 = 出错 + 慢 + 不可复现。CI/CD 把"代码提交 → 构建 → 测试 → 部署"全流程自动化:提交即验证、通过即发布、发布可追溯。本文讲 GitLab CI / GitHub Actions 流水线、自动化测试环节、以及测试/预发布环境自动部署的设计。
一、流水线设计
1.1 阶段划分
标准流水线阶段:
1. build 编译打包(Maven/Gradle)
2. test 自动化测试(单元/集成/压测)
3. quality 质量门禁(SonarQube/覆盖率)
4. package 构建镜像(Docker,见容器化章节)
5. deploy 部署(测试 → 预发布 → 生产)
门禁(Gate):
任一阶段失败 → 终止流水线
覆盖率不达标 → 阻断发布
人工审批 → 生产部署前// 流水线触发
- 提交/合并请求 → build + test + quality(快,分钟级)
- 合并到主干 → package + deploy 测试环境
- 打 Tag(v1.4.2)→ 预发布部署 + 验收
- 生产发布 → 灰度(见灰度章节)+ 审批1.2 GitLab CI 示例
// .gitlab-ci.yml
stages: [build, test, package, deploy]
build:
stage: build
image: maven:3.9-eclipse-temurin-17
script:
- mvn clean compile
cache: # 依赖缓存加速
paths: [.m2/repository]
test:
stage: test
script:
- mvn test
artifacts:
reports: { junit: target/surefire-reports/*.xml }
package:
stage: package
image: docker:24
services: [docker:24-dind]
script:
- docker build -t $CI_REGISTRY/game-logic:$CI_COMMIT_TAG .
- docker push $CI_REGISTRY/game-logic:$CI_COMMIT_TAG
only: [tags] # 打 Tag 才构建镜像二、自动化测试
2.1 测试分层
测试金字塔(游戏服务):
单元测试:纯逻辑(伤害公式、状态机、概率)
集成测试:DB/Redis/MQ 交互(Testcontainers)
协议测试:编解码、边界、异常包
压测:性能回归(基线对比,见压测章节)
重点测试对象(游戏特有):
服务端权威(恶意请求校验)
幂等(重复请求不重复发货)
防沉迷(时长/充值限制)
状态机(房间/对战流转)// 单元测试示例(伤害公式)
@Test
void damage_calculation() {
assertThat(calc.damage(100, 30, 1.5f)).isEqualTo(105);
}
// 集成测试(Testcontainers)
@Testcontainers
class PlayerDaoTest {
@Container static MySQLContainer mysql = ...;
// 真实 MySQL 验证 SQL
}2.2 质量门禁
质量门禁:
单元测试覆盖率(如 >= 70%)
静态扫描(SonarQube:Bug/漏洞/坏味道)
依赖漏洞扫描(OWASP Dependency-Check)
门禁作用:
合并前强制通过(MR Pipeline)
防止代码质量劣化
提前发现安全漏洞// 质量门禁示例
quality:
stage: quality
script:
- mvn sonar:sonar -Dsonar.qualitygate.wait=true
# 门禁未过 → 流水线失败,阻断合并三、部署流水线
3.1 环境部署
环境划分:
测试环境(每合并自动部署,联调用)
预发布环境(生产镜像 + 生产配置,验收用)
生产环境(灰度发布,审批后执行)
部署方式:
测试/预发布:Docker Compose 或 K8s 命名空间
生产:K8s 滚动更新(见容器化章节)
部署后自动化验证(冒烟测试)// 部署到测试环境(GitLab CI)
deploy-test:
stage: deploy
script:
- docker compose -f docker-compose.test.yml up -d --build
only: [main]
environment: test
// 部署到预发布(打 Tag 触发)
deploy-staging:
stage: deploy
script:
- kubectl set image deploy/game-logic game-logic=registry/game-logic:$CI_COMMIT_TAG
only: [tags]
environment: staging3.2 部署后验证
自动冒烟测试(部署后):
健康检查通过(readiness)
登录接口可通(冒烟用例)
关键链路验证(注册 → 登录 → 对局 → 结算)
失败 → 自动回滚
发布记录:
每个版本部署到哪、何时、谁审批
镜像 Tag 与代码 Commit 对应
一键回滚(保留上一版本镜像)// 冒烟测试脚本(部署后执行)
1. GET /actuator/health → 200
2. 注册测试账号 → 成功
3. 登录 → 成功
4. 创建房间 → 成功
5. 全部通过 → 标记部署成功
6. 任一失败 → 回滚 + 告警四、版本与回滚
4.1 版本管理
版本策略:
语义化版本:主.次.补丁(1.4.2)
打 Tag 触发生产构建
镜像 Tag = 版本号(registry/game-logic:1.4.2)
提交记录与版本对应(可追溯)
发布审批:
生产部署需要审批(合并请求 / 人工确认)
审批记录留档(审计)4.2 回滚
回滚策略:
代码回滚:revert 提交(但可能不彻底)
镜像回滚:切回上一版本镜像(推荐,快)
配置回滚:配置中心还原(见热更新)
回滚触发:
部署后验证失败
线上指标异常(监控告警)
灰度发现问题kubectl rollout undo deployment/game-logic
# 或直接切镜像
kubectl set image deploy/game-logic \
game-logic=registry/game-logic:1.4.1五、实现要点
CI/CD 核心:
流水线:build → test → quality → package → deploy
自动化测试:单元 + 集成 + 协议 + 压测 + 质量门禁
环境部署:测试自动部署、预发布验收、生产灰度
版本与回滚:语义化版本 + 镜像回滚 + 审批留档
常见坑:
流水线只构建不测试 → 门禁形同虚设
测试环境数据不干净 → 联调互相污染
生产部署无审批 → 事故
回滚预案缺失 → 出事手忙脚乱
与其他系统衔接:
容器镜像 → 容器化章节
发布策略 → 灰度发布章节
部署验证 → 监控告警章节
日志审计 → 发布记录可追溯