Durante alguns dias, procurei uma solução funcional para um erro
Error: EMFILE, too many open files
Parece que muitas pessoas têm o mesmo problema. A resposta usual envolve aumentar o número de descritores de arquivos. Então, eu tentei isso:
sysctl -w kern.maxfiles=20480
,
O valor padrão é 10240. Isso é um pouco estranho aos meus olhos, porque o número de arquivos que estou manipulando no diretório está abaixo de 10240. Ainda mais estranho, ainda recebo o mesmo erro depois de aumentar o número de descritores de arquivos .
Segunda questão:
Após várias pesquisas, encontrei uma solução alternativa para o problema "muitos arquivos abertos":
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);
Infelizmente ainda recebo o mesmo erro. O que está errado neste código?
Uma última pergunta (eu sou novo no javascript e no nó), estou desenvolvendo um aplicativo da web com muitas solicitações para cerca de 5.000 usuários diários. Tenho muitos anos de experiência em programação com outras linguagens como python e java. então originalmente pensei em desenvolver esta aplicação com django ou play framework. Descobri o nó e devo dizer que a ideia de modelo de E / S sem bloqueio é realmente agradável, sedutora e, acima de tudo, muito rápida!
Mas que tipo de problemas devo esperar com o nó? É um servidor Web comprovado em produção? Quais são as suas experiências?
fonte
lsof -i -n -P | grep "12843" | wc -l
== 4085 masulimit -a | grep "open files"
== (-n) 1024 alguma pista de como eu poderia ter mais arquivos abertos que o limite máximo?Usar o
graceful-fs
módulo de Isaac Schlueter (mantenedor do node.js.) é provavelmente a solução mais apropriada. Faz recuo incremental se EMFILE for encontrado. Ele pode ser usado como um substituto para ofs
módulo embutido .fonte
Não tenho certeza se isso vai ajudar alguém, comecei a trabalhar em um grande projeto com muitas dependências que me causaram o mesmo erro. Meu colega me sugeriu a instalação
watchman
usando o brew e isso resolveu esse problema para mim.Editar em 26 de junho de 2019: link do Github para vigia
fonte
Encontrei este problema hoje e, não encontrando boas soluções, criei um módulo para resolvê-lo. Fui inspirado pelo snippet do @ fbartho, mas queria evitar a substituição do módulo fs.
O módulo que escrevi é Filequeue e você o usa como o fs:
fonte
Você está lendo muitos arquivos. O nó lê os arquivos de forma assíncrona, estará lendo todos os arquivos de uma só vez. Então você provavelmente está lendo o limite 10240.
Veja se isso funciona:
fonte
Como todos nós, você é outra vítima de E / S assíncrona. Com chamadas assíncronas, se você fizer um loop em muitos arquivos, o Node.js começará a abrir um descritor de arquivo para cada arquivo para ler e aguardará a ação até você fechá-lo.
O descritor de arquivo permanece aberto até que o recurso esteja disponível no seu servidor para lê-lo. Mesmo que seus arquivos sejam pequenos e a leitura ou atualização seja rápida, isso leva algum tempo, mas, ao mesmo tempo, seu loop não para para abrir um novo descritor de arquivos. Portanto, se você tiver muitos arquivos, o limite será atingido em breve e você obterá um belo EMFILE .
Existe uma solução, criando uma fila para evitar esse efeito.
Graças às pessoas que escreveram Async , há uma função muito útil para isso. Existe um método chamado Async.queue , você cria uma nova fila com um limite e adiciona nomes de arquivos à fila.
Nota: Se você precisar abrir muitos arquivos, seria uma boa ideia armazenar quais arquivos estão abertos no momento e não reabri-los infinitamente.
Você pode ver que cada arquivo é adicionado à fila (nome do arquivo console.log), mas apenas quando a fila atual está abaixo do limite definido anteriormente.
async.queue obtém informações sobre a disponibilidade da fila por meio de um retorno de chamada, esse retorno de chamada é chamado apenas quando o arquivo de dados é lido e qualquer ação que você precisa executar é alcançada. (consulte o método fileRead)
Portanto, você não pode ficar impressionado com o descritor de arquivos.
fonte
Acabei de escrever um pequeno trecho de código para resolver esse problema, todas as outras soluções parecem muito pesadas e exigem que você altere a estrutura do programa.
Essa solução apenas interrompe todas as chamadas fs.readFile ou fs.writeFile para que não haja mais do que um número definido em andamento a qualquer momento.
fonte
Eu fiz todas as coisas acima mencionadas para o mesmo problema, mas nada funcionou. Eu tentei abaixo funcionou 100%. Alterações simples na configuração.
Limite definido da opção 1 (não funcionará na maioria das vezes)
verifique o limite disponível
Opção 2 Para aumentar o limite disponível para dizer 65535
adicione a seguinte linha a ela
execute isso para atualizar com a nova configuração
edite o seguinte arquivo
adicione as seguintes linhas a ele
edite o seguinte arquivo
adicione esta linha a ela
logout e login e tente o seguinte comando
Opção 3 Basta adicionar a linha abaixo
para /etc/systemd/system.conf e /etc/systemd/user.conf
fonte
Com gaita de foles, você só precisa mudar
=>
A gaita de fole ajuda a limitar o paralelo. mais detalhes: https://github.com/JacksonTian/bagpipe
fonte
Tive o mesmo problema ao executar o comando nodemon, então reduzi o nome dos arquivos abertos em texto sublime e o erro desapareceu.
fonte
EMFILE
erros e, por tentativa e erro, notei que o fechamento de algumas janelas Sublime resolveu o problema. Eu ainda não sei o porquê. Tentei adicionarulimit -n 2560
ao meu .bash_profile, mas isso não resolveu o problema. Isso indica a necessidade de mudar para Atom ?Com base na resposta do @ blak3r, aqui está um pouco de abreviação que eu uso caso ajude outros diagnósticos:
Se você estiver tentando depurar um script Node.js que está ficando sem descritores de arquivo, aqui está uma linha para fornecer a saída
lsof
usada pelo processo do nó em questão:Isso será executado de forma síncrona
lsof
filtrada pelo processo atual do Node.js. em execução e retornará os resultados via buffer.Em seguida, use
console.log(openFiles.toString())
para converter o buffer em uma sequência e registrar os resultados.fonte
esperar é uma solução geral para limitar execuções simultâneas de qualquer função que retorne promessas.
No seu caso, o código pode ser algo como:
fonte
Para usuários do nodemon : Basta usar o --ignore sinalizador para resolver o problema.
Exemplo:
fonte
Use o mais recente
fs-extra
.Eu tive esse problema
Ubuntu
(16 e 18) com bastante espaço para arquivos / descritores de soquete (conte comlsof |wc -l
).fs-extra
Versão usada8.1.0
. Após a atualização9.0.0
do "Erro: EMFILE, muitos arquivos abertos" desapareceram.Eu experimentei diversos problemas em diversos sistemas operacionais com sistemas de arquivos para manipulação de nós. Os sistemas de arquivos obviamente não são triviais.
fonte
Eu tive esse problema e o resolvi executando
npm update
e funcionou.Em alguns casos, pode ser necessário remover o node_modules
rm -rf node_modules/
fonte
Eu instalei o watchman, alterei o limite etc. e não funcionou no Gulp.
Reiniciar o iterm2 realmente ajudou.
fonte