为了账号安全,请及时绑定邮箱和手机立即绑定

从41分钟到8分钟:我是如何把我们的CI/CD流水线提速5倍的

简介

在软件开发的世界中,时间就是一切。持续集成/持续部署流水线可以加快过程,但有时正是流水线导致过程变慢,这听起来有点讽刺意味。最近一段时间,这正是我遇到的问题,我们使用Jenkins流水线时,每个构建的时间长达难以控制的41分钟。

我决心消除这种低效,分析、优化并改造了我们的工作流程,将时间从惊人的41分钟缩短到8分钟——整整5倍的提升!在这篇文章中,我会分享我遇到的问题、采取的解决办法以及一些可以用来大幅提升你工作流程效率的策略。

问题

我们的CI/CD流水线涉及了前后端的以下任务:

  • 代码检出(Checkout)
  • 静态代码分析:ESLint,SonarQube
  • 单元测试
  • 构建并推送Docker镜像
  • 预发布环境部署
  • 手动审批和生产部署

乍一看,管道挺结实的,但还是暴露了一些问题:

  1. 臃肿的Docker构建上下文
    在构建镜像时发送到Docker的所有文件已经增长到1.5GB,并且构建时间变得非常长。
  2. 重复安装依赖项
    流水线中的每个阶段都必须从头开始重新安装npm依赖项,造成了不必要的延迟。
  3. 糟糕的Docker镜像管理
    即使没有发生任何更改,Docker镜像也被重建并推送到仓库。
  4. 无法并行执行
    同样,所有任务,如代码静态检查或测试,都是依次执行的。
  5. 手动部署步骤
    由于需要手动更新AWS ECS任务定义,后端的部署耗时且容易出错。
解决办法:

这是我实现管道流程5倍优化效果的方法。

减小 Docker 构建上下文的大小

Docker 构建上下文过大,是因为未筛选的项目目录导致的。我们可以使用 .dockerignore 文件来排除一些不必要的文件,比如 node_moduleslogs 等。

重要文件 : .dockerignore

    node_modules # 存放项目依赖的模块    
    *.log # 项目日志文件    
    dist # 项目构建输出的文件夹    
    coverage # 测试覆盖率报告    
    test-results # 测试结果文件夹

影响如下:
将构建上下文大小从1.5GB减少到大约10MB,传输时间从30分钟减少到不到1分钟。

缓存依赖

每一个阶段都用了 npm install。我把它改成了 npm ci,确保可重现性,并且在 Jenkins 里启用了缓存。

命令更新通知

npm ci --cache ~/.npm

运行这个命令来安装依赖,使用指定的缓存目录 ~/.npm.

影响
将依赖安装耗时从每个步骤的3到4分钟减少到了不到20秒。

优化Docker镜像处理:

之前,构建流程会无条件地重建和推送Docker镜像。我增加了逻辑,用于比较本地和远程镜像的哈希值,只有在镜像发生变化时才推送。

更新后的逻辑:

    def remoteImageHash = sh(returnStdout: true, script: "docker inspect --format='{{.Id}}' $DOCKER_IMAGE:$DOCKER_TAG || echo ''").trim()  
    def localImageHash = sh(returnStdout: true, script: "docker images --no-trunc -q $DOCKER_IMAGE:$DOCKER_TAG").trim()  

    if (localImageHash != remoteImageHash) {  
        sh 'docker push $DOCKER_IMAGE:$DOCKER_TAG'  
    } else {  
        echo "镜像没有更新,跳过推送操作。"  
    }

影响效果
减少了不必要的推送,每次构建大约节省了3到5分钟。

并行运行静态分析和测试

我扩展了Jenkins流水线,使其能够使用parallel指令,从而使ESLint验证、SonarQube扫描和单元测试可以同时运行。

更新后的项目管道

    阶段('静态代码分析阶段') {  
        并行 {  
            阶段('前端 ESLint') {  
                执行 {  
                    步骤 {  
                        sh 'npm run lint'  
                    }  
                }  
            }  
            阶段('后端 SonarQube') {  
                执行 {  
                    在SonarQube环境配置下 {  
                        步骤 {  
                            sh 'sonar-scanner'  // 执行SonarQube扫描命令  
                        }  
                    }  
                }  
            }  
        }  
    }

效果
将静态分析和测试时间缩短了50%。

自动后台部署

手动更新 AWS ECS 任务定义既耗时又容易出错。我用 AWS CLI 自动化了这一步。

自动脚本

    def 任务定义Json = """  
    {  
        "family": "$ECS任务定义名称",  
        "containerDefinitions": [  
            {  
                "name": "后端",  
                "image": "$DOCKER镜像:$DOCKER标签",  
                "memory": 512,  
                "cpu": 256,  
                "essential": "必需的"  
            }  
        ]  
    }  
    """  
    sh "echo '${任务定义Json}' > task-definition.json"  
    sh "aws ecs 注册任务定义 --cli-input-json file://task-definition.json --region $AWS区域"  
    sh "aws ecs 更新服务 --cluster $ECS集群名称 --service $ECS服务名称 --task-definition $ECS任务定义名称 --region $AWS区域"

效果
这样简化了部署过程,节省了5分钟的时间。

结果

经过这些优化,流水线时间从41分钟缩短到仅8分钟——提高了5倍,即原来的五分之一。以下是详细的比较。

对比表

学到的
  1. 日志是你的最佳伙伴:通过分析日志来找到瓶颈。
  2. 缓存拯救难题:有效利用缓存可以大幅缩短构建时间。
  3. 并行运行任务:使用并行执行可以快速节省时间。
  4. 排除无关文件:用 .dockerignore 文件排除无关文件,性能显著提升。
  5. 自动化重复任务:自动化消除错误并提速工作流程。
总结一下

优化 CI/CD 管道是一次令人印象深刻的经历。通过定位关键瓶颈并实施战略性更改,将一个耗时 41 分钟的繁琐任务转变为只需 8 分钟的高效流程。结果如何?更快的部署,更快乐的开发人员们,以及更多时间专注于功能。

如果你遇到管道效率低的问题,可以从首先识别瓶颈开始,启用缓存,并行执行任务,并自动化重复的任务。即使是小小的调整也能带来巨大的效果。

你通过优化CI/CD流水线节省了多久时间?在下方评论区分享你的经验与技巧!

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消