关于node.js:使用大型ZIP包的Node Express进行邮编创建过程

Zip Create Process with Node Express of large ZIP packages

目标

我们站在一个小规模的站点上,用户(浏览器客户端)将在其中选择图像文件(每个文件284 KB),然后请求Node Express Server将其捆绑为ZIP以便下载到Web客户端。

问题与设计约束

  • 最终的ZIP可能约为50 MB-5 GB。因此,我们想
    在ZIP制作过程中为用户提供运行进度栏
    建造。 (我们假设浏览器将针对
    实际下载进度)。
  • 虽然我们希望请求量少
    (一次1-2个请求)。但是,我们不想完全占用我们的4个
    核心服务器处理器,因此我们希望最大程度地减少占用快速服务器的同步调用。
  • 给定ZIP的大小,我们不能期望zip仅在内存中组装
  • 还有其他我们应该担心的问题吗?

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

那么,鉴于上面列出的设计约束/目标,下列哪个软件包对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
  • zipstream:https://www.npmjs.com/package/zip-stream

我在上面看到的是,大多数软件包首先收集文件,然后将它们最终确定到内存中,然后通过管道将它们传递给http请求(可能不适合5GB的数据,或者我丢失了什么)。有些人似乎可以使用磁盘,但问题是在添加每个文件时是否会发生更新事件?

其他人似乎完全不同步,我看不到每个文件添加到ZIP包后如何获得运行进度值。


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

  • JSZIP主要用于浏览器
  • EasyZip是JSZIP的节点包装,但未提供
    创建过程中的进度通知
  • Express-Zip是一种内存中表达友好的RES解决方案(但
    可能无法处理我们正在谈论的ZIP的大小)

    • ZIP-Stream是Archiver下的基础实用程序。封存者有
      排队服务,所以应该只是用户归档程序
  • YAZL可能有效,但是界面对于进度而言更加复杂
    跟踪比存档

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

  • 表达友好
  • 低内存占用
  • 对于我们创建的特定图像档案,速度高达7ZIP(我们不需要压缩,文件很大等)。对于其他类型的档案,您的性能可能会受到25%的影响
  • 它不允许您附加到现有档案(这是我们想要的功能之一),但是adm-zip可能会弥补这一差距

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

  • 在流中找到字符串很麻烦
  • 它导致上下文切换读取流,
  • 您有一个易碎的解决方案试图处理输出流输出的内容(例如,对于7zip,它有时会使计数器反跳30%,有时反跳1%),以及其他易碎解决方案的来源。


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.

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

这样的命令行将在添加每个新文件时显示在stdout上添加到存档的每个文件的进度:

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

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

作为子进程运行此进程将使您的nodejs进程可以自由处理其他请求,并使子进程可以独立于nodejs来管理自己的内存。

7zip程序可处理具有适当内存使用量的超大存档和文件。借助正确的标记来获得stdout的进度并将其作为子进程运行,它似乎可以满足您的所有要求。