优化 jenkins 构建 vue 项目时间

本贴最后更新于 1606 天前,其中的信息可能已经水流花落

1599814231932.jpg

本次优化在未进行 webpack 配置修改的前提下,可以减少 40+ 秒,据前端反馈 webpack 优化后还可以再减少 40+ 秒

我这里使用了单独的 jenkins slave 用来专门处理编译耗时的 job,工作目录/data/jenkins/

使用 tmpfs,进行内存换时间

mount -t tmpfs -o size=1G,nr_inodes=10k,mode=0700 tmpfs /data/jenkins

如果 inode 设置过小很容易占满,df -i 可以查看到 100%,根据实际使用情况调整

mount -o remount,size=2G,nr_inodes=100k /data/jenkins

设置开机挂载,编辑/etc/fstab

tmpfs /data/jenkins tmpfs defaults,size=2G,nr_inodes=100k,mode=0700 0 0

使用 yarn 进行依赖管理

之前有看到使用 npm ci 的方式,不过 npm v5 暂时不支持,安装 yarn

npm install -g yarn

配置 yarn 的缓存路径和全局安装路径

yarn config set cache-folder /data/jenkins/yarn-cache yarn config set global-folder "/data/jenkins/yarn-global"

配置淘宝源,也可以换成私库

yarn config set registry https://registry.npm.taobao.org

避免报错:The engine "node" is incompatible with this module

yarn config set ignore-engines true

使用 --prefer-offline 模式。

  • 如果设置为 --prefer-offline 则优先使用缓存数据,如果没有匹配的缓存数据,则从远程仓库下载。
  • 如果设置为 --prefer-online 则优先使用网络数据,忽略缓存数据,这种模式可以及时获取最新的模块。
yarn --prefer-offline

禁用 progress

当设置 progress 为 true 时, 时将会显示进度条,把它设置为 false 可小幅提高 的速度。

// npm set progress=false && npm run build:${ENV} yarn run build:${ENV} --no-progress

附:清理缓存

//npm cache clean --force yarn cache clean

复用 node_modules

jenkins 构建时不清理 workspace,复用 node_modules,这里我使用 mount --bind 的方式把/data/jenkins/node_modules 挂载到 $WORKSPACE/node_modules,job 完成后 umount

最终 jenkins pipeline

pipeline { // agent any agent { label 'tmpfs-slave' } options { ansiColor('xterm') buildDiscarder(logRotator(daysToKeepStr: '1', numToKeepStr: '5')) } tools { Git 'git_2.19.1' } environment { Git = 'http://172.19.76.222/adminfe/adminfe-admin-fe.git' IMAGE_GROUP = "adminfe" //对应 harbor 镜像分组 K8S_NAMESPACE = "${ENV}-${IMAGE_GROUP}" REPLICAS = 1 TEMPLATE="deployment-frontend.yml" PROJECT = sh(script: "echo ${GIT} | awk -F '/' '{print \$NF}' | awk -F '.' '{print \$1}'", returnStdout: true).trim() ENV = sh(script: "echo ${JOB_BASE_NAME} | awk -F '-' '{print \$1}'", returnStdout: true).trim() HARBOR_HOST = 'test-devops-harbor.demo.com' ZIP = "target" PATH = "/data/node-v8.11.1/bin:$PATH" DOCKER_IMAGE = "${IMAGE_GROUP}/${JOB_BASE_NAME}:${VERSION_VALUE}" MAIL_TO = "admin@demo.com" CHECK_TAG = sh(script: "echo ${BRANCH_OR_TAG} | awk -F '/' '{if (\$3) print \$3; else print \$1}'", returnStdout: true).trim() // 分支或 tag VERSION_VALUE = "${CHECK_TAG}-${TIME}" // 分支或 tag TIME = sh(script: "date '+%Y%m%d%H%M%S'", returnStdout: true).trim() } stages { stage ('代码获取') { steps { echo "\033[46;30m************************************************ 拉取代码开始 ************************************************\033[0m" // deleteDir() // 清理工作目录 Git credentialsId: 'gitlab_username_password_credential', url: "${GIT}" sh '[ -n "${CHECK_TAG}" ] && Git checkout ${CHECK_TAG} || { echo -e "切换至指定的 tag 的版本,tag:${CHECK_TAG} 不存在或为空,请检查输入的 tag!" && exit 111; }' echo "\033[46;30m************************************************ 拉取代码结束 ************************************************\033[0m" } } stage ('代码编译') { steps { echo "\033[46;30m************************************************ 编译打包开始 ************************************************\033[0m" sh "git pull || true" sh "[ -d 'node_modules' ] && echo 'Directory Exists' || mkdir node_modules && mount --bind /data/jenkins/node_modules node_modules" sh "yarn config set ignore-engines true && yarn config set registry https://registry.npm.taobao.org && yarn --prefer-offline && yarn run build:${ENV} --no-progress" echo "\033[46;30m************************************************ 编译打包结束 ************************************************\033[0m" } } stage('镜像构建') { steps { echo "\033[46;30m************************************************ 镜像构建开始 ************************************************\033[0m" script { sh "/usr/bin/cp -f /data/template/docker/Dockerfile-frontend Dockerfile" sh "docker build --build-arg PROJECT=${PROJECT} -t ${HARBOR_HOST}/${DOCKER_IMAGE} ." sh "docker push ${HARBOR_HOST}/${DOCKER_IMAGE}" sh "docker rmi ${HARBOR_HOST}/${DOCKER_IMAGE}" } echo "\033[46;30m************************************************ 镜像构建结束 ************************************************\033[0m" } } stage('发布服务至 kubernetes 集群') { steps { script { echo "\033[46;30m************************************************ 发布服务至 kubernetes 集群开始 ************************************************\033[0m" sh "cp /data/template/k8s/${TEMPLATE} ${TEMPLATE}" sh "sed -i -e 's#{IMAGE_URL}#${HARBOR_HOST}/${DOCKER_IMAGE}#g;s#{PROJECT}#${PROJECT}#g;s#{IMAGE_GROUP}#${IMAGE_GROUP}#g;s#{K8S_NAMESPACE}#${K8S_NAMESPACE}#g;s#{REPLICAS}#${REPLICAS}#g;' ${TEMPLATE}" sh "kubectl --kubeconfig /data/kubecfg/test-cluster cluster-info && kubectl --kubeconfig /data/kubecfg/test-cluster get nodes" sh "kubectl --kubeconfig /data/kubecfg/test-cluster apply -f ${TEMPLATE} --namespace=${K8S_NAMESPACE}" echo "\033[46;30m************************************************ 发布服务至 kubernetes 集群结束 ************************************************\033[0m" } } } } post { always { script{ sh "umount node_modules" // 解除目录挂载 echo "\033[46;30m************************************************ 邮件通知开始 ************************************************\033[0m" def jobUserId, jobUserName wrap([$class: 'BuildUser']) { jobUserId = "${BUILD_USER_ID}" jobUserName = "${BUILD_USER}" jobUserEmail = "${BUILD_USER_EMAIL}" } if (currentBuild.currentResult == "ABORTED" || currentBuild.currentResult == "FAILURE" || currentBuild.currentResult == "UNSTABLE" ){ mail to: "devops@demo.com,'${jobUserEmail}", subject: "PineLine '${JOB_NAME}' (${BUILD_NUMBER})构建失败", body: "操作人: ${jobUserName}\n 操作事项: 执行执行 PineLine '${JOB_NAME}' (${BUILD_NUMBER})\n 于 ${TIME} 构建 job 失败\n 项目 url 为 ${BUILD_URL}console", charset:"UTF-8" } else { mail to: "devops@demo.com", subject: "PineLine '${JOB_NAME}' (${BUILD_NUMBER})构建成功", body: "操作人: ${jobUserName}\n 操作事项: 执行执行 PineLine '${JOB_NAME}' (${BUILD_NUMBER})\n 于 ${TIME} 进入 kubernetes 集群发布状态\n 请前往 rancher 查看发布详情", charset:"UTF-8" } echo "\033[46;30m************************************************ 邮件通知结束 ************************************************\033[0m" } } } }
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    54 引用 • 25 回帖 • 7 关注
5 操作
fish2018 在 2020-09-25 10:27:53 更新了该帖
fish2018 在 2020-09-22 19:27:51 更新了该帖
fish2018 在 2020-09-22 19:26:02 更新了该帖
fish2018 在 2020-09-11 17:57:07 更新了该帖 fish2018 在 2020-09-11 16:59:38 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...