NodeJS загружает файлы со 100% загрузкой процессора

Я пробовал две разные библиотеки: multer и formidable для обработки загрузки файлов в узел, и оба они используют 100% ЦП во время загрузки.

Это общая проблема узла? И как люди справляются с этим в среде с высокой степенью параллелизма?

Версия узла: v0.10.36 (я даже пробовал другие версии, такие как v0.11.x или v0.10.33)

Грозный пример

Picture.upload = function(user, req, cb) {
    var formidable = require('formidable')

    var form = new formidable.IncomingForm();
    form.uploadDir = "./uploads";
    form.maxFieldsSize = app.settings.uploadMaxSize * 1024 * 1024;
    form.maxFields = 1000;

    form.parse(req, function(err, fields, files) {
        cb(null, files);
    });
}

Пример мультипликатора

app.use(multer({ dest: './uploads/',
    rename: function (fieldname, filename) {
       return filename+Date.now();
    },
    limits: {
       files: 1,
       fileSize: app.settings.uploadMaxSize * 1024 * 1024
    }
})); // after I process the file from req.files

Файл загружен как multipart/form-data.

Я использую loopback, но не думаю, что это имеет значение.


person marka.thore    schedule 05.02.2015    source источник
comment
Можете ли вы опубликовать пример кода? Просто дикое предположение, может быть, это актуально github.com/felixge/node-formidable/issues /109 ?   -  person Evan P    schedule 05.02.2015
comment
Я не думаю, что это связано, потому что моя проблема связана с процессором, а не с использованием памяти. Во всяком случае, я добавил два фрагмента кода   -  person marka.thore    schedule 05.02.2015
comment
вы можете попробовать следующий код? fs.createReadStream(filePath) .pipe(fs.createWriteStream('public/images/' + filename)) .on('close', function () { fs.unlink(filePath, function () { callback(null, '/images/' + filename); }); }); используйте его в качестве контроллера в конечной точке загрузки.   -  person Evan P    schedule 05.02.2015
comment
Я не понял, как проверить ваш фрагмент. Вы хотите скопировать файл после его загрузки? (так что я должен поместить его в form.parse?)   -  person marka.thore    schedule 05.02.2015
comment
В какой операционной системе вы используете узел, в котором вы испытываете это состояние?   -  person Mark    schedule 13.02.2015
comment
Вы уверены, что стоит беспокоиться об использовании 100% CPU? Например, если это происходит на вашей тестовой машине, и ваша тестовая машина больше ничего не делает, вероятно, это то, что должно происходить. Лучше задать вопрос: блокирует ли это цикл обработки событий? Вы тестировали на это?   -  person mwarren    schedule 13.02.2015
comment
Вы вообще обрабатываете этот файл после загрузки или просто сохраняете его на диск?   -  person tsturzl    schedule 14.02.2015
comment
Я думаю, что в производственной среде с высокой степенью параллелизма решение заключается в простом добавлении большего количества ЦП на сервер. Простите за это. Ну, я тоже работаю с загрузками, но без multer или formidable. Попробуйте и вы. Это будет значительно быстрее.   -  person Gabriel Tomitsuka    schedule 14.02.2015
comment
@GabrielTomitsuka Это просто не ответ. Здесь есть проблема. Добавление большего количества ЦП вовсе не является высококонкурентным, так как вам потребуется учитывать почти весь ЦП для каждой загрузки, что нереально в большинстве сценариев.   -  person tsturzl    schedule 15.02.2015
comment
Пожалуйста, предоставьте подробную информацию о любой обработке, которая происходит после загрузки файла, и, возможно, проанализируйте загрузку ЦП без этой постобработки. Если вы уже сделали это, возможно, стоит провести бенчмаркинг, чтобы увидеть, действительно ли вы получаете значительную потерю производительности. Другие вещи, которые приходят на ум, это то, что вы можете столкнуться с проблемами из-за ограничений гипервизора. Вы запускаете это на виртуальной машине или на «голом железе»? Какая ОС (и версия ядра). Если вы используете Linux, не могли бы вы предоставить статистику через mpstat?   -  person tsturzl    schedule 15.02.2015
comment
Я только что протестировал очень простую загрузку файлов в тестовом приложении, и 11-мегапиксельный фильм, похоже, заставляет процессор перемещаться с 3% до 10% на экземпляре Amazon EC2 t2.micro. Не слишком научно или статистически значимо, но, возможно, указывает на то, что, возможно, стоит провести еще один анализ, как предлагает @tsturzi? Я использовал экспресс и Multer, но не использовал loopback. Кроме того, как и другие, я думаю, что предлагаемое использование ЦП необходимо интерпретировать осторожно, поскольку большинство ОС управляют нагрузкой, чтобы наилучшим образом использовать доступный ЦП (поэтому могут выполняться домашние задачи с низким приоритетом, когда, например, мало что происходит).   -  person Mick    schedule 16.02.2015
comment
Я также провел тесты локально и не смог воспроизвести ваш результат. В моем случае я редко видел, чтобы процессор превышал 3%. Я вижу комментарий // after I process the file from req.files и у меня такое ощущение, что, возможно, вы обрабатываете файл после его загрузки в том же потоке выполнения, что и загрузка файла. Это может привести к блокировке, в которой я бы рекомендовал что-то вроде kue или какой-либо другой метод перемещения логически интенсивных код на рабочий узел.   -  person tsturzl    schedule 16.02.2015


Ответы (1)


В среде с высокой степенью параллелизма, если задача заставляет процессор достичь 100%, к сожалению, узел будет заблокировать. Я предполагаю, что загрузка файла означает то же самое, что и обслуживание статических ресурсов. здесь много обсуждается, почему nodejs не подходит для обслуживания статический контент. Вместо этого используйте nginx или apache.

Другое решение — делегировать загрузку рабочему процессу или системе очередей. См., например, ZMQ.

person Harry Moreno    schedule 12.02.2015
comment
Это неправда. Процентное использование ЦП основано на многих вещах, а загрузка — это почти все операции ввода-вывода. 100% ЦП не всегда будет блокироваться. Только на логически интенсивных методах. На самом деле это может быть просто очень полный цикл обработки событий, что имеет смысл, поскольку multer использует потоки. Постановка загрузки в очередь не имеет смысла, вы не можете просто поставить запрос в ZMQ, а затем повторно подключить клиента к рабочему. Люди ставят в очередь уже загруженные вещи, чтобы обработать их, например, манипулировать изображениями. - person tsturzl; 14.02.2015
comment
Эй, вы можете сделать свой собственный ответ. Посмотрим, примут ли ???? - person Harry Moreno; 14.02.2015
comment
Я полагаю, что мог бы, однако я бы сделал это, только если бы имел хорошее представление о том, что именно происходит. Хотя очевидно, что простая задача не должна использовать процессор на 100% в любом случае. Я имел в виду, что если бы это было так, то это прямо не указывает на блокировку. Хотя это, вероятно, представляет собой ухудшение производительности. - person tsturzl; 15.02.2015