欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 前端技术 > html >内容正文

html

build 之前执行task-ag凯发k8国际

发布时间:2024/10/8 html 30 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 build 之前执行task_一次npm前端项目的ci-build速度优化 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

base

基础设施部分,项目发布在中国区亚马逊云,使用了aws的容器服务(ecs)、容器注册表(ecr)、对象存储(s3)、弹性计算(ec2)

源码管理使用atlassian出品的bitbucket,一款git体系的代码仓库

ci/cd使用jenkins与pipline实现与维护

项目开发语言为nodejs

项目代号salmon

项目打包&发布使用npm&docker

一、标准的发布流程

  • 开发工程师提交pr,审核通过,merge后触发jenkins pipline执行job;
  • jenkins调度slave执行jenkinsfile,各stage编排了一个job中的每个步骤;
  • slave将源码拉取到workspace;
  • 构建,读项目目录的dockerfile将源码打包成镜像;编译过程写在dockerfile中的npm install && npm build ;
  • 发布,将编译/打包好的镜像推送到远端私有仓库(aws-ecr);
  • 部署,调用aws cli,更新aws-ecs任务定义&服务,等待服务滚动发布
  • 二、症结反馈

    同事a:“目前自动化的ci/cd流程在线上环境比较缓慢,可能拖累开发测试工作,请寻找一些优化点”

    同事b:“我的项目在本地打包只要一两分钟,但是线上构建流程要花10 分钟”

    三、成因分析

    查阅jenkins console output && 分析jenkin blue-ocean的时间统计,主要分为三个关键步骤:

    stage{'build'} 编译代码 // > 10min

    stage{'publish'} 推到仓库 // < 10s

    stage{'deploy'} 运行服务 // < 1min

    随后继续分析“构建”这一步,时间消耗在docker build,进一步分析各个step,发现npm run build消耗了最多时间,约为9分钟

    刚刚提到,我们线上发布流程是容器化的,包括jenkins的slave,也是在ec2虚拟机上面启动的jnlp-slave-container,再执行docker build命令,编译过程写在dockerfile当中。

    与开发工程师本地构建这一过程相比,容器化的ci流,每一次构建,它的基础设施都是纯净的、无状态的,除了推送到远端的image也是没有文件留存的。即传统基础设施与容器化纯净环境的差异,可能就是build速度差异的关键。

    四、问题复现

    我选用了一台ec2(2核8gb),用于复现非容器化的构建流程并统计耗时,模拟开发者在自己的mac开发环境从源码到build的过程。

    step1.

    $ mkdir /code

    拉取最新slamom项目代码,执行npm install,随后执行5次npm build,初次build约8分钟,随后的4次为2分半。

    step2.

    在同一个项目目录(/code),回滚至5个版本前的salmon代码 git reset --hard head^5;

    执行npm install,随后执行5次npm build,初次build约1分钟,随后的4次为1分钟。

    step3.

    回复至第一步的最新版代 git reset --hard head;

    执行npm install,随后执行5次npm build,初次build约2分半,随后的4次为2分半。

    下图为脚本输出记录。

    1~5 step1;101~105 step2

    小结:在已build过的项目目录进行后续build,会大大减少这一过程耗时,是否是因为生成了编译的缓存文件?

    step4.

    复现与审查ci流程,主要为3步,多次复现发现项目目录容量增长如下

    • 拉代码 # 14mb
    • npm install # 434mb
    • npm run build #525mb

    已知.next/目录下为npm run build编译后的成品项目代码,删除这部分后,有470mb

    经过多重文件对比,定位到在编译后的项目中,node_modules/目录下会有一个.cache 目录

    多次调试,验证了build前后差30mb文件的问题,确实是在 .cache 目录中

    将.cache目录的内容应用到已执行npm install未build的目录,有以下场景:

    • 同版本号的代码,build时间 8min → 2.5min
    • 临近两三个版本号的代码,build时间 8min → 4min
    • 差较大版本号的代码,build时间仍为 8min

    五、优化设计

    接下来考虑的是如何将这个目录,或称缓存池,维护和利用起来?考虑ci流基本都在小版本号之前变更,决定将这个缓存目录维护在线上,build之前拉取,build之后推送。

    我使用了aws的s3服务,s3有一个目录同步功能(sync)

    文档地址:https://docs.amazonaws.cn/cli/latest/userguide/cli-services-s3-commands.html

    # s3 sync 命令使用如下语法。可能的源-目标组合有:# 本地文件系统到 amazon s3# amazon s3 到本地文件系统# amazon s3 到 amazon s3$ aws s3 sync [--options]

    在ec2测试机上运行的结果:

    六、优化编译脚本(即dockerfile)

    改造了原有的node-builder镜像,添加了aws cli工具用以操作s3,imageurl:

    ***.http://dkr.ecr.cn-northwest-1.amazonaws.com.cn/node-builder-with-awscli:normal

    改写后的dockerfile摘录如下:

    # 添加了build过程与缓存池的pull&oush交互-20191213 from ***.dkr.ecr.cn-northwest-1.amazonaws.com.cn/node-builder-with-awscli:normal as builder# create app directory workdir /usr/src/app# install app dependencies # a wildcard is used to ensure both package.json and package-lock.json are copied # where available (npm@5 ) # bundle app source copy . .run npm cache clear --force && npm_config_registry=https://registry.npm.taobao.org npm install && mkdir node_modules/.cache && aws s3 sync --quiet s3://zhiwen-build-cache/salmon/.cache/ node_modules/.cache/ && npm run build && aws s3 sync --quiet node_modules/.cache/ s3://zhiwen-build-cache/salmon/.cache/ && rm -rf node_modules/.cachefrom node:10.15.3-alpineworkdir /usr/src/appcopy --from=builder /usr/src/app .#user nodeexpose 3000 cmd [ "npm", "start" ]

    七、验证优化效果

    摘录了jenkins blue-ocean的统计,一个jenkinsfile包含4个stage的执行时间

    salmon-dev-661 : stage{&#39;build&#39;} 耗时4m7ssalmon-dev-661 : next build 耗时2m41s

    对比一个未优化的ci流

    salmon-dev-399 : stage{&#39;build&#39;} 耗时9m43ssalmon-dev-661 : next build 耗时8m4s

    提速效果还是比较明显的

    八、关于线上缓存池

    • 缓存池会越来越大,会不会反过来拖累build时间
    • 设置了创建时间大于5天即删除的缓存池过期策略,看看好不好使,或把这个时间改更短些

    这是当时实施留存的两个issue,根据后续的运行观察:

    • 缓存池(一个s3 bucket的目录)保存了大概3000~3600个静态文件,build样本为dev环境的14个,时间均在4分半到5分钟
    • sync操作需要20s~30s
    • 5天的缓存池过期策略能够正常运行,也比较匹配开发周期

    九、问题与总结

    其他项目没有使用 .next 框架或webpack打包工具可能铺展不开这套 .cache 缓存池的优化策略。

    本文使用的工具都比较简单,得益较大的是在优化探索中

    • 问题采集与复现
    • 数据对比
    • 成因分析
    • 优化方案设计
    • 搜寻适合工具
    • 思路举一反三
    • 成果检验

    这些项目工程逻辑与解决问题的思考和方法论,希望能对自己和读者都有些启发

    总结

    以上是ag凯发k8国际为你收集整理的build 之前执行task_一次npm前端项目的ci-build速度优化的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

    • 上一篇:
    • 下一篇:
    网站地图