В течение нескольких дней я искал рабочее решение ошибки
Error: EMFILE, too many open files
Похоже, у многих людей такая же проблема. Обычный ответ включает в себя увеличение количества файловых дескрипторов. Итак, я попробовал это:
sysctl -w kern.maxfiles=20480
,
Значение по умолчанию - 10240. Это немного странно для меня, потому что число файлов, которые я обрабатываю в каталоге, меньше 10240. Даже странно, что я все еще получаю ту же ошибку после увеличения числа дескрипторов файлов. ,
Второй вопрос:
После нескольких поисков я нашел решение проблемы «слишком много открытых файлов»:
var requestBatches = {};
function batchingReadFile(filename, callback) {
// First check to see if there is already a batch
if (requestBatches.hasOwnProperty(filename)) {
requestBatches[filename].push(callback);
return;
}
// Otherwise start a new one and make a real request
var batch = requestBatches[filename] = [callback];
FS.readFile(filename, onRealRead);
// Flush out the batch on complete
function onRealRead() {
delete requestBatches[filename];
for (var i = 0, l = batch.length; i < l; i++) {
batch[i].apply(null, arguments);
}
}
}
function printFile(file){
console.log(file);
}
dir = "/Users/xaver/Downloads/xaver/xxx/xxx/"
var files = fs.readdirSync(dir);
for (i in files){
filename = dir + files[i];
console.log(filename);
batchingReadFile(filename, printFile);
К сожалению, я все еще получаю ту же ошибку. Что не так с этим кодом?
Последний вопрос (я новичок в javascript и узле), я нахожусь в процессе разработки веб-приложения с большим количеством запросов для около 5000 пользователей в день. У меня многолетний опыт программирования на других языках, таких как Python и Java. поэтому первоначально я подумал о разработке этого приложения с Django или Play Framework. Затем я открыл узел и должен сказать, что идея неблокирующей модели ввода / вывода действительно хороша, соблазнительна и, скорее всего, очень быстра!
Но каких проблем мне ожидать с узлом? Это проверенный производственный веб-сервер? Каковы ваши переживания?
источник
lsof -i -n -P | grep "12843" | wc -l
== 4085 ноulimit -a | grep "open files"
== (-n) 1024 какая-нибудь подсказка, как я могу иметь больше открытых файлов, чем максимальное ограничение?Использование
graceful-fs
модуля Исаака Шлютера (сопровождающий node.js), вероятно, является наиболее подходящим решением. Это делает постепенный откат, если встречается EMFILE. Его можно использовать как замену встроенногоfs
модуля.источник
Я не уверен, поможет ли это кому-нибудь, я начал работать над большим проектом с большим количеством зависимостей, который выдал мне ту же ошибку. Мой коллега предложил мне установить
watchman
с помощью brew, и это помогло мне решить эту проблему.Редактировать 26 июня 2019 года: Github ссылка на сторожа
источник
Я столкнулся с этой проблемой сегодня, и, не найдя хороших решений, я создал модуль для ее решения. Я был вдохновлен фрагментом @ fbartho, но хотел избежать перезаписи модуля fs.
Модуль, который я написал, - Filequeue , и вы используете его так же, как fs:
источник
Вы читаете слишком много файлов. Узел читает файлы асинхронно, он будет читать все файлы одновременно. Таким образом, вы, вероятно, читаете предел 10240.
Посмотрите, работает ли это:
источник
Как и все мы, вы являетесь еще одной жертвой асинхронного ввода-вывода. При асинхронных вызовах, если вы зациклились на большом количестве файлов, Node.js начнет открывать файловый дескриптор для каждого файла для чтения, а затем будет ждать действия, пока вы его не закроете.
Файловый дескриптор остается открытым, пока на вашем сервере не появится ресурс для его чтения. Даже если ваши файлы небольшие, а чтение или обновление выполняется быстро, это займет некоторое время, но в то же время ваш цикл не останавливается, чтобы открыть дескриптор новых файлов. Так что, если у вас слишком много файлов, предел скоро будет достигнут, и вы получите красивый ЭМФИЛЬ .
Есть одно решение - создать очередь, чтобы избежать этого эффекта.
Спасибо людям, которые написали Async , для этого есть очень полезная функция. Существует метод Async.queue , вы создаете новую очередь с ограничением, а затем добавляете имена файлов в очередь.
Примечание: если вам нужно открыть много файлов, было бы неплохо хранить, какие файлы открыты в данный момент, и не открывать их бесконечно.
Вы можете видеть, что каждый файл добавляется в очередь (имя файла console.log), но только тогда, когда текущая очередь находится ниже предела, установленного ранее.
async.queue получает информацию о доступности очереди через обратный вызов, этот обратный вызов вызывается только тогда, когда файл данных читается, и любое действие, которое вам нужно сделать, достигнуто. (см. метод fileRead)
Таким образом, вы не можете быть перегружены дескриптором файлов.
источник
Я только что закончил писать небольшой фрагмент кода, чтобы решить эту проблему самостоятельно, все другие решения кажутся слишком тяжелыми и требуют изменения структуры вашей программы.
Это решение просто останавливает любые вызовы fs.readFile или fs.writeFile, чтобы в любой момент времени в рейсе было не более установленного номера.
источник
Я сделал все вышеупомянутые вещи для той же проблемы, но ничего не получалось. Я попробовал ниже, он работал на 100%. Простые изменения конфигурации.
Вариант 1 установить лимит (он не будет работать большую часть времени)
проверить доступный лимит
Вариант 2 Чтобы увеличить доступный лимит, скажем, 65535
добавить следующую строку к нему
запустите это, чтобы обновить новую конфигурацию
отредактируйте следующий файл
добавить следующие строки к нему
отредактируйте следующий файл
добавить эту строку к нему
Выйдите из системы и войдите в систему и попробуйте следующую команду
Вариант 3 Просто добавьте строку ниже
в /etc/systemd/system.conf и /etc/systemd/user.conf
источник
С волынкой нужно просто поменять
=>
Волынка поможет вам ограничить параллель. более подробная информация: https://github.com/JacksonTian/bagpipe
источник
У меня была такая же проблема при запуске команды nodemon, поэтому я уменьшил имя файлов, открытых в возвышенном тексте, и ошибка исчезла.
источник
EMFILE
ошибки и методом проб и ошибок заметил, что закрытие некоторых Sublime окон решило проблему. Я до сих пор не знаю почему. Я попытался добавитьulimit -n 2560
в свой .bash_profile, но это не решило проблему. Означает ли это, что вместо этого нужно перейти на Atom ?Основываясь на ответе @ blak3r, вот несколько сокращений, которые я использую на случай, если это поможет другим диагностировать:
Если вы пытаетесь отладить скрипт Node.js, на котором заканчиваются файловые дескрипторы, вот строка, чтобы дать вам вывод,
lsof
использованный рассматриваемым процессом узла:Это будет работать синхронно
lsof
фильтром текущего запущенного процесса Node.js и возвращать результаты через буфер.Затем используйте
console.log(openFiles.toString())
для преобразования буфера в строку и записи результатов.источник
cwait - это общее решение для ограничения одновременного выполнения любых функций, которые возвращают обещания.
В вашем случае код может быть что-то вроде:
источник
Для пользователей nodemon : просто используйте флаг --ignore для решения проблемы.
Пример:
источник
Используйте последние
fs-extra
.У меня была такая проблема на
Ubuntu
(16 и 18) с большим количеством пространства файлов / сокетов-дескрипторов (считайте сlsof |wc -l
). Используемаяfs-extra
версия8.1.0
. После обновления9.0.0
«Ошибка: EMFILE, слишком много открытых файлов» исчезло.Я сталкивался с различными проблемами в разных ОС с файловой системой обработки узлов. Файловые системы явно не тривиальны.
источник
У меня была эта проблема, и я решил ее, запустив,
npm update
и это сработало.В некоторых случаях вам может понадобиться удалить node_modules
rm -rf node_modules/
источник
Я установил сторож, изменил лимит и т. Д., И это не сработало в Gulp
Перезапуск iterm2 действительно помог, хотя.
источник