Zip Create Process with Node Express 大型 ZIP 包
Zip Create Process with Node Express of large ZIP packages
目标
我们建立了一个低容量站点,用户(浏览器客户端)将 select 图像文件(每个文件 284 KB)然后请求 Node Express 服务器将它们捆绑到 ZIP 中以供下载到网络客户端。
问题与设计限制
- 生成的 ZIP 可能约为 50 MB - 5 GB。因此我们想
在压缩过程中给用户一个 运行 进度条
建。 (我们假设浏览器将 运行 更新为
实际下载的进度)。
- 虽然我们预计请求量很少
(一次 1-2 个请求)。但是,我们不想完全占用我们的 4
核心服务器处理器,因此我们希望尽量减少占用快速服务器的同步调用。
- 鉴于 ZIP 的大小,我们不能期望 zip 仅在内存中组装
- 我们还有什么其他问题需要担心吗?
问题
我们假设 运行 7zip 作为子进程是错误的,因为我们不会得到任何关于 258KB 文件中有多少已添加到 ZIP 的 运行 状态。
鉴于上面列出的 constraints/goals 设计,以下哪些软件包是非常 Node/ExpressJS 友好的软件包?
- 存档器:https://www.npmjs.com/package/archiver
- jszip: https://www.npmjs.com/package/jszip
- easyzip: https://www.npmjs.com/package/easy-zip
- expresszip: https://www.npmjs.com/package/express-zip
- 压缩流:https://www.npmjs.com/package/zip-stream
我在上面看到的是大多数包首先收集文件,然后将它们最终确定到内存中,然后通过管道将它们传送到 http 请求(可能不适合 5GB 的数据,或者我遗漏了什么)。有些似乎能够使用磁盘,但问题是添加每个文件时是否获得更新事件?
其他似乎是完全异步的,我不明白你如何在每个文件添加到 ZIP 包时获得 运行 进度值。
We assume that running 7zip as a child process is bad, since we would not get any running status as to how many of the 258KB files had been added to the ZIP.
这似乎是一个错误的假设。
像这样的命令行将在添加每个新文件时在标准输出上显示添加到存档的每个文件的进度:
7z a -bsp1 -bb3 test.7z *
因此,您可以使用子进程模块从 node.js 启动它,您应该能够在它发生时捕获 stdout 进度。您将需要使用 spawn
,而不是 exec
,这样您就可以实时获取 stdout
数据。
运行 这作为子进程将使您的 nodejs 进程自由地服务于其他请求,并允许子进程独立于 nodejs 管理自己的内存。
7zip 程序以适当的内存使用量处理非常大的档案和文件。有了正确的标志来获得 stdout 的进展并且 运行 它作为一个子进程,它似乎可以满足您的所有要求。
上面列出的软件包。大多数都不合适
- JSZIP主要针对浏览器
- EasyZip 是 JSZIP 的节点包装器,但它不提供
创建过程中的进度通知
- Express-Zip 是一种内存中表达友好的 RES 解决方案(但
可能不会处理我们正在谈论的 ZIP 的大小)
- ZIP-Stream 是 Archiver 下的底层实用程序。归档器有
排队服务,所以应该只是 user archiver
- YAZL 可能有用,但界面更复杂
比 Archiver
跟踪
我们选择了 Archiver,因为它具有所需的大部分功能:
- 表达友好
- 低内存占用
- 对于我们创建的特定图像存档,速度与 7ZIP 一样快(我们不需要压缩,文件很大等)。对于其他类型的存档,您的性能可能会下降 25%
- 它不允许您追加到现有档案(这是我们想要的一项功能),但 adm-zip 可能会提供这种差距
至于 7zip 解决方案。我们往往不喜欢从派生的子进程中读取标准输出流的内部。
- 在流中查找字符串很麻烦
- 它会导致上下文切换以读取流,
- 你有一个脆弱的解决方案试图处理输出流输出的内容(例如,在 7zip 的情况下,它有时会超过 30%,有时会超过 1%),以及其他脆弱解决方案的来源。
目标
我们建立了一个低容量站点,用户(浏览器客户端)将 select 图像文件(每个文件 284 KB)然后请求 Node Express 服务器将它们捆绑到 ZIP 中以供下载到网络客户端。
问题与设计限制
- 生成的 ZIP 可能约为 50 MB - 5 GB。因此我们想 在压缩过程中给用户一个 运行 进度条 建。 (我们假设浏览器将 运行 更新为 实际下载的进度)。
- 虽然我们预计请求量很少 (一次 1-2 个请求)。但是,我们不想完全占用我们的 4 核心服务器处理器,因此我们希望尽量减少占用快速服务器的同步调用。
- 鉴于 ZIP 的大小,我们不能期望 zip 仅在内存中组装
- 我们还有什么其他问题需要担心吗?
问题
我们假设 运行 7zip 作为子进程是错误的,因为我们不会得到任何关于 258KB 文件中有多少已添加到 ZIP 的 运行 状态。
鉴于上面列出的 constraints/goals 设计,以下哪些软件包是非常 Node/ExpressJS 友好的软件包?
- 存档器:https://www.npmjs.com/package/archiver
- jszip: https://www.npmjs.com/package/jszip
- easyzip: https://www.npmjs.com/package/easy-zip
- expresszip: https://www.npmjs.com/package/express-zip
- 压缩流:https://www.npmjs.com/package/zip-stream
我在上面看到的是大多数包首先收集文件,然后将它们最终确定到内存中,然后通过管道将它们传送到 http 请求(可能不适合 5GB 的数据,或者我遗漏了什么)。有些似乎能够使用磁盘,但问题是添加每个文件时是否获得更新事件?
其他似乎是完全异步的,我不明白你如何在每个文件添加到 ZIP 包时获得 运行 进度值。
We assume that running 7zip as a child process is bad, since we would not get any running status as to how many of the 258KB files had been added to the ZIP.
这似乎是一个错误的假设。
像这样的命令行将在添加每个新文件时在标准输出上显示添加到存档的每个文件的进度:
7z a -bsp1 -bb3 test.7z *
因此,您可以使用子进程模块从 node.js 启动它,您应该能够在它发生时捕获 stdout 进度。您将需要使用 spawn
,而不是 exec
,这样您就可以实时获取 stdout
数据。
运行 这作为子进程将使您的 nodejs 进程自由地服务于其他请求,并允许子进程独立于 nodejs 管理自己的内存。
7zip 程序以适当的内存使用量处理非常大的档案和文件。有了正确的标志来获得 stdout 的进展并且 运行 它作为一个子进程,它似乎可以满足您的所有要求。
上面列出的软件包。大多数都不合适
- JSZIP主要针对浏览器
- EasyZip 是 JSZIP 的节点包装器,但它不提供 创建过程中的进度通知
- Express-Zip 是一种内存中表达友好的 RES 解决方案(但
可能不会处理我们正在谈论的 ZIP 的大小)
- ZIP-Stream 是 Archiver 下的底层实用程序。归档器有 排队服务,所以应该只是 user archiver
- YAZL 可能有用,但界面更复杂 比 Archiver 跟踪
我们选择了 Archiver,因为它具有所需的大部分功能:
- 表达友好
- 低内存占用
- 对于我们创建的特定图像存档,速度与 7ZIP 一样快(我们不需要压缩,文件很大等)。对于其他类型的存档,您的性能可能会下降 25%
- 它不允许您追加到现有档案(这是我们想要的一项功能),但 adm-zip 可能会提供这种差距
至于 7zip 解决方案。我们往往不喜欢从派生的子进程中读取标准输出流的内部。
- 在流中查找字符串很麻烦
- 它会导致上下文切换以读取流,
- 你有一个脆弱的解决方案试图处理输出流输出的内容(例如,在 7zip 的情况下,它有时会超过 30%,有时会超过 1%),以及其他脆弱解决方案的来源。