背景
以 Jenkins 服务器为例, 在构建内部的这个项目时, CE 每部署一次服务, 最快 6 分钟, 最
慢将近 13 分钟左右. 遇到多个项目并发打包会因为资源占用等问题时间会延长, 甚至出现过
几次 20 分钟以上的情况.
所以经常收到一些友情提示: 比如像这样的截图, 往往对方只发一张图, 却什么都不说:
原因
在了解原因之前, 我们先回顾一下历史, 也就是当年为什么要用 Yarn. 从这段历史中, 我们
可以分析出来慢的原因.
Yarn 工具没有推出之前, 通常是使用 NPM 进行依赖管理的, 早期的 NPM 它有一个致命的
缺陷; 需要等一个包, 完全安装好后, 在对下一个包做处理; 它没有并发能力, 所以才不会
涉及到高 IO 的问题, 牺牲的是等待时间.
NPM 遇到相同版本的依赖库时, 会重新下载一遍这个包; 因为它原生不具备缓存能力, 所以
只能重新下载. 这也不会涉及 IO 问题, 因为它牺牲了下载时间和 node_modules 文件夹的体
积(这里是提前引用概念, 下面第四条中有介绍).
所以当时, 我们引用了 Yarn 工具来提升安装依赖的速度.
(1) 它最特殊的是, 具备锁 (lock) 文件, 你从哪下载文件, 你团队的人就从哪下载文件, 避
免包版本不一致的问题. 能解决我线下好使啊, 怎么到你那就不行, 诸如此类的问题.
(2) 会缓存它下载的每个包, 所以无需重复下载.
(3) 具备离线模式, 之前安装过的包会被写入缓存目录, 以后安装就直接从缓存中复制过来,
这样做的本质是减少重复下载, 减少不必要的网络请求.
(4) 为了减少 node_modules 体积, 会对依赖次数做选举, 把引用频率高的类库放到顶级目录.
我们已经了解, 它是依赖文件缓存的方式, 提升了效率问题; 仅仅是做选举, 就已经引发了
高频 IO 的操作, 因为它要分析引用次数来回的移动目录. webpack 打包构建情况也是类似,
具体就不在展开细说.
现象
所以我们有了一个印象, 前端工程下载后, 会做很多 IO 操作. 这对 SSD 磁盘很有效. 如果
是机械硬盘, 遇到高频读写, 性能就会很慢. 这是 Yarn 在做依赖库选举而优化磁盘占用时,
机械硬盘所消耗的时间耗时 13 分钟:
这种情况我们很难避免, 只有几种选择:
1. 后退, 使用 NPM 工具, 选择等待牺牲网络下载时间, 这条路走不通.
2. Jenkins 更换 SSD 磁盘, 更换硬件实际上是最好的方案, 短期内也走不通.
3. 优化 Yarn 依赖库的选举方案, Yarn PnP 还不太成熟, 我们还在调研中, 有坑, 也走不通.
解决方案
当时的情况是, 正常的方案都无法走通了. 直到有一天我的同事提供一个思路, 说他当年在 Windows
下片时, 为了加快 Copy 速度把内存当磁盘用了, Windows 设置这个东西很简单. 你们看看
Linux 支不支持. 随后我们就开始调研, 本机测试后发现可行.
然后我们以线下的的环境做试点, 部署脚本改好了测试近一周, 发现可行.
优化前, 最高 23 分钟(开篇第一张图), 现在平均 3 分钟:
另一个项目优化前, 平均 8 分钟:
优化后, 平均 49 秒:
本次主要是给大家, 提供一个解决 IO 问题的思路. 我们使用的是 RAM disk 中的 temfs
方案. 技术对比看下方链接的文章就行, 很简单:
参考链接
来源: https://www.cnblogs.com/wubaiqing/p/11460766.html