1

目标

我们建立了一个低容量站点,用户(浏览器客户端)将在其中选择图像文件(每个文件 284 KB),然后请求 Node Express 服务器将它们捆绑到 ZIP 中以下载到 Web 客户端。

问题和设计约束

  • 生成的 ZIP 可能约为 50 MB - 5 GB。因此,我们希望在构建 ZIP 时为用户提供一个正在运行的进度条。(我们假设浏览器将提供有关实际下载进度的运行更新)。
  • 虽然我们预计请求量很少(一次 1-2 个请求)。但是,我们不想完全占用我们的 4 核服务器处理器,因此我们希望尽量减少占用快速服务器的同步调用。
  • 鉴于 ZIP 的大小,我们不能期望 zip 仅在内存中组装
  • 还有其他我们需要担心的问题吗?

问题

我们假设将 7zip 作为子进程运行是不好的,因为我们不会得到任何关于有多少 258KB 文件已添加到 ZIP 的运行状态。

那么考虑到上面列出的设计约束/目标,以下哪些包是对 Node/ExpressJS 非常友好的包?

我在上面看到的是大多数包首先收集文件,然后将它们最终确定到内存中,然后将它们传送到 http 请求(可能对 5GB 的数据不利,或者我遗漏了什么)。有些似乎能够使用磁盘,但问题是每个文件添加时是否会获取更新事件?

其他人似乎是完全异步的,我看不出在将每个文件添加到 ZIP 包时如何获得运行进度值。

4

2 回答 2

2

上面列出的软件包。大多数都不合适

  • JSZIP主要针对浏览器
  • EasyZip 是 JSZIP 的节点包装器,但它在创建期间不提供进度通知
  • Express-Zip 是一种内存中快速友好的 RES 解决方案(但可能无法处理我们正在谈论的 ZIP 的大小)
    • ZIP-Stream 是 Archiver 的底层实用程序。Archiver 有排队服务,所以应该只是用户 archiver
  • YAZL 可能有效,但进度跟踪的界面比 Archiver 更复杂

我们选择了 Archiver,因为它具有大部分所需的功能:

  • 快递友好
  • 低内存占用
  • 对于我们创建的特定图像存档,速度快至 7ZIP(我们不需要压缩,文件很大等)。其他类型的存档可能会降低 25% 的性能
  • 它不允许您附加到现有档案(这是我们想要的一个功能),但 adm-zip 可能会提供这个空白

至于 7zip 解决方案。我们往往不喜欢从衍生的子进程中读取标准输出流的内脏。

  • 在流中查找字符串很麻烦
  • 它导致上下文切换读取流,
  • 你有一个脆弱的解决方案试图处理输出流输出的内容(例如,在 7zip 的情况下,它有时会跳出计数器 30% 有时会跳出 1%),以及其他脆弱解决方案的来源。
于 2017-05-30T14:53:41.027 回答
0

我们假设将 7zip 作为子进程运行是不好的,因为我们不会获得任何关于有多少 258KB 文件已添加到 ZIP 的运行状态。

这似乎是一个错误的假设。

像这样的命令行将在添加每个新文件时显示添加到标准输出存档中的每个文件的进度:

7z a -bsp1 -bb3 test.7z *

因此,您可以使用子进程模块从 node.js 启动它,并且您应该能够在 stdout 进度发生时捕获它。您将需要使用spawn,而不是exec这样您就可以stdout实时获取数据。

将其作为子进程运行将使您的 nodejs 进程可以自由地为其他请求提供服务,并允许子进程管理自己的内存,独立于 nodejs。

7zip 程序以适当的内存使用处理非常大的档案和文件。使用正确的标志来获得标准输出的进展并将其作为子进程运行,它似乎满足您的所有要求。

于 2017-05-26T19:25:18.677 回答