Процесс создания Zip с Node Express для больших пакетов ZIP

Цель

Мы работаем над сайтом с небольшим объемом, где пользователи (клиент браузера) выбирают файлы изображений (284 КБ на файл), а затем запрашивают Node Express Server, чтобы связать их в ZIP для загрузки в веб-клиент.

Проблемы и ограничения дизайна

  • Результирующий ZIP может быть порядка 50 МБ - 5 ГБ. Поэтому мы хотели бы дать пользователю индикатор выполнения во время создания ZIP. (Мы предполагаем, что браузер будет предоставлять текущие обновления о ходе фактической загрузки).
  • Пока мы ожидаем небольшой объем запросов (1-2 запроса за раз). Однако мы не хотим полностью связывать наш 4-ядерный серверный процессор, поэтому мы хотим минимизировать синхронные вызовы, которые связывают экспресс-сервер.
  • Учитывая размер ZIP, мы не можем ожидать, что он будет собран только в памяти
  • Есть ли другие проблемы, о которых нам следует беспокоиться?

Вопрос

Мы предполагаем, что запуск 7zip как дочернего процесса - это плохо, так как мы не получили бы никакого запущенного статуса относительно того, сколько из 258 КБ файлов было добавлено в ZIP.

Итак, какие из следующих пакетов являются очень дружественными для Node/ExpressJS пакетами с учетом ограничений / целей дизайна, перечисленных выше?

Что я вижу выше, так это то, что большинство пакетов сначала собирают файлы, а затем финализируют их в память, а затем направляют их по запросу http (вероятно, не подходит для 5 ГБ данных или я что-то упустил). Некоторые, кажется, могут использовать диск, но вопрос в том, можно ли получать события обновления при добавлении каждого файла?

Другие, кажется, полностью асинхронны, и я не вижу, как вы получите текущее значение прогресса при добавлении каждого файла в ZIP-пакет.

2 ответа

Решение

Из пакетов, перечисленных выше. Большинство не подходили

  • JSZIP в основном для браузера
  • EasyZip является упаковщиком узлов для JSZIP, но он не предоставляет уведомления о прогрессе при создании
  • Express-Zip - это удобное решение для быстрого восстановления в памяти (но, вероятно, оно не будет соответствовать размеру ZIP, о котором мы говорим)
    • ZIP-Stream является основной утилитой под Archiver. Архиватор имеет службы очередей, так что нужно просто пользовательский архиватор
  • YAZL может работать, но интерфейс для отслеживания прогресса более сложен, чем Archiver

Мы выбрали Archiver, так как он имел большинство желаемых функций:

  • Экспресс дружественный
  • низкий объем памяти
  • так же быстро, как 7ZIP для конкретных архивов изображений, которые мы создаем (нам не нужно сжимать, файлы имеют большой размер и т. д.). Возможно, производительность других типов архивов снизится на 25%
  • Он не позволяет вам добавлять к существующим архивам (это была одна из функций, которую мы хотели), но adm-zip может обеспечить этот пробел

Что касается решения 7zip. Нам не нравится читать внутренности стандартного потока вывода из порожденного дочернего процесса.

  • Это грязно, чтобы найти строки в потоках
  • это вызывает переключение контекста для чтения потока,
  • у вас есть хрупкое решение, пытающееся разобраться с тем, что производит выходной поток (например, в случае с 7zip, иногда он увеличивает счетчик на 30%, иногда на 1%), а также с другими источниками хрупких решений.

Мы предполагаем, что запуск 7zip как дочернего процесса - это плохо, так как мы не получили бы никакого запущенного статуса относительно того, сколько из 258 КБ файлов было добавлено в ZIP.

Это кажется ложным предположением.

Такая командная строка покажет прогресс для каждого файла, добавленного в архив на стандартный вывод при добавлении каждого нового файла:

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

Таким образом, вы можете запустить его из node.js, используя дочерний модуль процесса, и вы сможете отслеживать прогресс stdout, как это происходит. Вам нужно будет использовать spawnне exec так что вы можете получить stdout данные живут так, как это происходит.

Выполнение этого в качестве дочернего процесса позволит вашему процессу nodejs свободно обслуживать другие запросы и позволит дочернему процессу управлять своей собственной памятью, независимой от nodejs.

Программа 7zip обрабатывает очень большие архивы и файлы с соответствующим использованием памяти. С правильными флагами, чтобы получить прогресс для stdout и запуск его как дочерний процесс, он, кажется, отвечает всем вашим требованиям.

Другие вопросы по тегам