Durante algunos días he buscado una solución funcional a un error
Error: EMFILE, too many open files
Parece que muchas personas tienen el mismo problema. La respuesta habitual implica aumentar el número de descriptores de archivo. Entonces, he intentado esto:
sysctl -w kern.maxfiles=20480
,
El valor predeterminado es 10240. Esto es un poco extraño a mis ojos, porque la cantidad de archivos que manejo en el directorio es inferior a 10240. Aún más extraño, sigo recibiendo el mismo error después de aumentar la cantidad de descriptores de archivo .
Segunda pregunta:
Después de varias búsquedas, encontré una solución para el problema de "demasiados archivos abiertos":
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);
Lamentablemente, sigo recibiendo el mismo error. ¿Qué está mal con este código?
Una última pregunta (soy nuevo en javascript y nodo), estoy en el proceso de desarrollar una aplicación web con muchas solicitudes para aproximadamente 5000 usuarios diarios. Tengo muchos años de experiencia en programación con otros lenguajes como Python y Java. originalmente pensé en desarrollar esta aplicación con django o play framework. Luego descubrí el nodo y debo decir que la idea del modelo de E / S sin bloqueo es realmente agradable, seductora y, sobre todo, muy rápida.
Pero, ¿qué tipo de problemas debo esperar con el nodo? ¿Es un servidor web probado en producción? Cuales son tus experiencias
fuente
lsof -i -n -P | grep "12843" | wc -l
== 4085 peroulimit -a | grep "open files"
== (-n) 1024 ¿ alguna pista de cómo podría tener más archivos abiertos que el límite máximo?Usar el
graceful-fs
módulo de Isaac Schlueter (mantenedor de node.js) es probablemente la solución más adecuada. Realiza un retroceso incremental si se encuentra EMFILE. Se puede usar como un reemplazo directo para elfs
módulo incorporado .fuente
No estoy seguro de si esto ayudará a alguien, comencé a trabajar en un gran proyecto con muchas dependencias que me arrojó el mismo error. Mi colega me sugirió instalar
watchman
con brew y eso solucionó este problema.Edición el 26 de junio de 2019: enlace de Github a watchman
fuente
Me encontré con este problema hoy, y al no encontrar buenas soluciones para él, creé un módulo para abordarlo. Me inspiró el fragmento de @fbartho, pero quería evitar sobrescribir el módulo fs.
El módulo que escribí es Filequeue , y lo usas como fs:
fuente
Estás leyendo demasiados archivos. El nodo lee los archivos de forma asincrónica, leerá todos los archivos a la vez. Entonces probablemente estés leyendo el límite 10240.
Vea si esto funciona:
fuente
Como todos nosotros, usted es otra víctima de E / S asíncrona. Con llamadas asíncronas, si recorre muchos archivos, Node.js comenzará a abrir un descriptor de archivo para cada archivo a leer y luego esperará la acción hasta que lo cierre.
El descriptor de archivo permanece abierto hasta que el recurso esté disponible en su servidor para leerlo. Incluso si sus archivos son pequeños y la lectura o actualización es rápida, lleva algo de tiempo, pero al mismo tiempo su ciclo no se detiene para abrir el nuevo descriptor de archivos. Entonces, si tiene demasiados archivos, pronto se alcanzará el límite y obtendrá un hermoso EMFILE .
Hay una solución, crear una cola para evitar este efecto.
Gracias a las personas que escribieron Async , hay una función muy útil para eso. Hay un método llamado Async.queue , crea una nueva cola con un límite y luego agrega nombres de archivo a la cola.
Nota: Si tiene que abrir muchos archivos, sería una buena idea almacenar qué archivos están actualmente abiertos y no volver a abrirlos infinitamente.
Puede ver que cada archivo se agrega a la cola (nombre de archivo console.log), pero solo cuando la cola actual está por debajo del límite establecido previamente.
async.queue obtiene información sobre la disponibilidad de la cola a través de una devolución de llamada, esta devolución de llamada solo se llama cuando se lee el archivo de datos y se logra cualquier acción que tenga que hacer. (ver método fileRead)
Por lo tanto, no puede sentirse abrumado por el descriptor de archivos.
fuente
Acabo de terminar de escribir un pequeño fragmento de código para resolver este problema yo mismo, todas las otras soluciones parecen demasiado pesadas y requieren que cambie la estructura de su programa.
Esta solución solo detiene cualquier llamada fs.readFile o fs.writeFile para que no haya más de un número establecido en vuelo en un momento dado.
fuente
Hice todo lo mencionado anteriormente para el mismo problema, pero nada funcionó. Lo intenté a continuación, funcionó al 100%. Cambios de configuración simples.
Opción 1 establecer límite (no funcionará la mayor parte del tiempo)
consultar límite disponible
Opción 2 Para aumentar el límite disponible para decir 65535
agregue la siguiente línea
ejecutar esto para actualizar con nueva configuración
edite el siguiente archivo
agregue las siguientes líneas
edite el siguiente archivo
agregue esta línea
cerrar sesión e iniciar sesión y probar el siguiente comando
Opción 3 Simplemente agregue la siguiente línea en
a /etc/systemd/system.conf y /etc/systemd/user.conf
fuente
Con la gaita, solo necesitas cambiar
=>
La gaita te ayuda a limitar el paralelo. Más detalles: https://github.com/JacksonTian/bagpipe
fuente
Tuve el mismo problema al ejecutar el comando nodemon, así que reduje el nombre de los archivos abiertos en texto sublime y el error desapareció.
fuente
EMFILE
errores y, mediante prueba y error, noté que al cerrar algunas ventanas Sublime se resolvió el problema. Aún no sé por qué. Intenté agregarulimit -n 2560
a mi .bash_profile, pero eso no resolvió el problema. ¿Indica esto la necesidad de cambiar a Atom ?Sobre la base de la respuesta de @ blak3r, aquí hay un poco de taquigrafía que uso en caso de que ayude a otros diagnósticos:
Si está tratando de depurar un script Node.js que se está quedando sin descriptores de archivo, aquí hay una línea para proporcionarle la salida
lsof
utilizada por el proceso de nodo en cuestión:Esto se ejecutará sincrónicamente
lsof
filtrado por el proceso actual Node.js en ejecución y devolverá los resultados a través del búfer.Luego, use
console.log(openFiles.toString())
para convertir el búfer en una cadena y registre los resultados.fuente
cwait es una solución general para limitar las ejecuciones concurrentes de cualquier función que devuelva promesas.
En su caso, el código podría ser algo como:
fuente
Para usuarios de nodemon : simplemente use el indicador --ignore para resolver el problema.
Ejemplo:
fuente
Utiliza lo último
fs-extra
.Tuve ese problema en
Ubuntu
(16 y 18) con un montón de espacio de descriptores de archivo / socket (contar conlsof |wc -l
). Usadofs-extra
versión8.1.0
. Después de la actualización de9.0.0
"Error: EMFILE, demasiados archivos abiertos" desapareció.He experimentado diversos problemas en diversos sistemas operativos con sistemas de archivos de manejo de nodos. Los sistemas de archivos obviamente no son triviales.
fuente
Tuve este problema, lo resolví ejecutando
npm update
y funcionó.En algunos casos, es posible que deba eliminar node_modules
rm -rf node_modules/
fuente
Instalé watchman, cambié el límite, etc. y no funcionó en Gulp.
Sin embargo, reiniciar iterm2 realmente ayudó.
fuente