CI/CD基础:从传统部署到持续交付的演进
大家好,我是这次课程的主讲。做CI/CD这块有些年头了,踩过的坑不少,积累的经验也挺多。今天咱们先聊聊最基础的东西——CI/CD到底是干什么的,它怎么就从传统部署一步步演化过来了。
说白了,CI/CD解决的是一件事:让软件交付更快、更稳。我刚开始做开发那会儿,项目上线还是“人肉部署”模式,那滋味,懂的都懂。
为什么需要CI/CD?从一次痛苦的上线说起
我记得刚工作第二年,经历过一次印象特深的上线。周五下午三点,项目经理说“今晚发版”。代码合并花了两小时,冲突一大堆。手动编译、打包、上传服务器,每一步都得盯着。结果到晚上十点,生产环境报错——少了个配置文件。回滚?回滚脚本都没写。那一晚,整个团队搞到凌晨三点。
你想想看,这种模式的问题在哪?
- 手工操作多:编译、测试、部署全靠人敲命令
- 反馈周期长:代码提交到线上验证,动辄几小时甚至几天
- 环境差异大:开发环境能跑,测试环境报错,生产环境又不一样
- 回滚靠运气:基本没想过“怎么快速恢复”这回事
核心矛盾:业务要求快速迭代,但手工部署流程又慢又脆弱。CI/CD就是专门解决这个矛盾的。
| 阶段 | 传统部署痛点 | CI/CD带来的改变 |
|---|---|---|
| 代码集成 | 一周合并一次,冲突爆炸 | 每日多次集成,小步快跑 |
| 测试验证 | 上线前集中测试,时间不够 | 每次提交自动触发测试,及早发现 |
| 部署发布 | 手动操作,易出错 | 自动化流水线,一键部署 |
| 回滚恢复 | 靠备份文件,常常不靠谱 | 版本化部署,秒级回滚 |
嗯,这里要注意:CI/CD不是某个工具或某个脚本,它是一套自动化流程和文化的集合。我见过很多团队上了Jenkins就觉得自己有CI/CD了,但实际上只做了自动化编译,后面测试、部署还是人工。
持续集成:让“合代码”不再可怕
持续集成,英文叫Continuous Integration,简称CI。它的核心逻辑是:尽早合并代码,尽早发现问题。
我在项目中遇到过这样的团队:开发各自在特性分支上干两周,到合并时才发现架构冲突了,改得头破血流。这就是忘了CI的本质。
CI的理想实践是这样的:
- 开发人员每天至少一次向主干分支提交代码
- 每次提交触发自动化构建和测试
- 如果构建失败,开发团队立即修复,不让红线过夜
我曾经帮一个团队优化CI流程,从每周一次集成提升到每天5-6次。磨合了两周后,代码冲突减少了80%以上。这就是持续集成的力量。
小技巧:CI的触发点越早越好。最好在开发人员push代码的那一刻就开始跑。不要等到下班前才触发,那时大家心态都松了。
持续交付:让发布变成“小决定”
持续交付(Continuous Delivery,CD)是CI的自然延伸。CI保证代码每次提交都是可集成的,CD则保证集成后的代码随时可以发布到生产环境。
说白了,CD就是在CI的基础上加上了自动化部署流水线。代码通过测试后,自动部署到类生产环境做进一步验证,整个过程标准、可重复。
我记得有个金融客户,原来发版要走两周的变更审批流程。上了CD之后,他们把部署标准化、自动化,审批流程也简化了。现在一个补丁从提交到线上,最快20分钟搞定。
关键区别:持续交付不等于持续部署。持续交付每次都会生成可发布的版本,但需要手动触发生产环境的部署。持续部署则是全自动,所有通过流水线的变更都自动上线。对于大多数企业,建议先从持续交付开始。
CI/CD的核心价值:不只是“自动化”
很多人把CI/CD简单理解成“自动化工具”。其实它带来的更深层价值是:
- 降低风险:小批量变更,每次影响范围可控
- 加速反馈:代码一提交,几分钟内就能知道有没有问题
- 提高团队效率:开发人员不用把时间花在手动部署上
- 质量内建:从编码阶段就开始验证,而不是等到上线前
我建议每个团队在推行CI/CD之前,先问自己三个问题:
- 你们的代码提交频率是多少?少于每天一次,先别谈CD
- 测试是自动跑的,还是靠人手工点?自动化覆盖率够不够?
- 部署过程能一键回滚吗?如果不能,说明流程还没成熟
实践中的CI/CD:从“能用”到“好用”
光讲理论没意思,咱们看一个实际的CI配置文件,感受一下:
# .gitlab-ci.yml 示例
stages:
- build
- test
- package
- deploy
build-job:
stage: build
script:
- echo "编译代码..."
- mvn compile
test-job:
stage: test
script:
- echo "运行自动化测试..."
- mvn test
package-job:
stage: package
script:
- echo "打包制品..."
- mvn package -DskipTests
deploy-staging:
stage: deploy
script:
- echo "部署到测试环境..."
- scp target/app.jar user@staging-server:/opt/app/
environment:
name: staging
你看,这个配置文件里定义了四个阶段:构建、测试、打包、部署。每次代码push到仓库,GitLab Runner就会自动按顺序执行这些任务。如果某个阶段失败了,流水线停住,开发者立刻收到通知。
我个人习惯在测试阶段加一个“失败快速退出”的逻辑——单元测试跑不过就直接停止,别浪费时间去做后续步骤。这能节省不少流水线时间。
建议:刚开始推CI/CD时,别追求一步到位。先把“编译+单元测试”自动化了,稳定后再加集成测试、代码扫描、自动部署。小步迭代,团队更容易接受。
嗯,第一章先讲到这里。CI/CD的核心逻辑很简单——用自动化流程替代手工操作,让每次代码变更都经过标准化的验证。不管你用的是Jenkins、GitLab CI还是GitHub Actions,本质都是一样的。后面我们会深入讲灰度验证和分层支持,把这些基础打牢了,后面的内容才能更好地理解。