Nuestro servidor recientemente se quedó sin descriptores de archivos, y con respecto a eso tengo algunas preguntas. ulimit -n
se supone que me da la cantidad máxima de descriptores de archivo abiertos. Ese número es 1024. Verifiqué la cantidad de descriptores de archivos abiertos ejecutando lsof -u root |wc -l
y obtuve 2500 fds. Eso es mucho más que 1024, así que supuse que eso significaría que el número 1024 es por proceso, no por usuario, como lo hice yo. Bueno, corrí lsof -p$PidOfGlassfish|wc -l
y obtuve 1300. Esta es la parte que no entiendo. Si ulimit -n
no es el número máximo de procesos por usuario o por proceso, ¿para qué sirve? ¿No se aplica al usuario root? Y si es así, ¿cómo podría obtener los mensajes de error sobre la falta de descriptor de archivo?
EDITAR: La única forma en que puedo tener sentido ulimit -n
es si aplica la cantidad de archivos abiertos (como se indica en el manual de bash) en lugar de la cantidad de identificadores de archivos (diferentes procesos pueden abrir el mismo archivo). Si este es el caso, simplemente enumerar el número de archivos abiertos (grepping en '/', excluyendo así los archivos mapeados en memoria) no es suficiente:
lsof -u root |grep /|sort -k9 |wc -l #prints '1738'
Para ver realmente la cantidad de archivos abiertos, necesitaría filtrar en la columna de nombre para imprimir solo las entradas únicas. Por lo tanto, lo siguiente es probablemente más correcto:
lsof -u root |grep /|sort -k9 -u |wc -l #prints '604'
El comando anterior espera resultados en el siguiente formato de lsof:
java 32008 root mem REG 8,2 11942368 72721 /usr/lib64/locale/locale-archive
vmtoolsd 4764 root mem REG 8,2 18624 106432 /usr/lib64/open-vm-tools/plugins/vmsvc/libguestInfo.so
Esto al menos me da un número menor que 1024 (el número reportado por ulimit -n
), por lo que parece un paso en la dirección correcta. "Desafortunadamente" No estoy experimentando ningún problema con la falta de descriptores de archivos, por lo que me será difícil validar esto.
fuente
Respuestas:
Probé esto en Linux versión 2.6.18-164.el5 - Red Hat 4.1.2-46. Pude ver que el ulimit se aplica por proceso.
El parámetro se establece a nivel de usuario, pero se aplica a cada proceso.
Por ejemplo: 1024 era el límite. Se iniciaron múltiples procesos y los archivos abiertos por cada uno se contaron usando
No hubo errores cuando la suma de archivos abiertos por múltiples procesos cruzó 1024. También verifiqué el recuento de archivos únicos combinando los resultados para diferentes procesos y contando archivos únicos. Los errores comenzaron a aparecer solo cuando el recuento de cada proceso cruzó 1024. (java.net.SocketException: demasiados archivos abiertos en los registros de proceso)
fuente
lsof -p$PidOfGlassfish|wc -l
me diste 1300? Supongo que los dos enfoques para contar difieren de alguna manera. Si no es así, ¿tal vez el límite no se aplica al usuario root?ls -l
lugar dels
? Este último tiene una línea adicional (por ejemplototal 5
) cuando hay 5 archivos. En tal caso, usarls -l
en el ejemplo anterior informaría 6 no 5. Yo usols /proc/<pid>/fd | wc -l
.ls -l
me da una entrada por línea, que luego canalizo en otra cosa. Por supuesto, esto también sucede cuando la tubería es normalls
(pero no de otra manera).El ulimit es para filehandles. Se aplica a archivos, directorios, sockets, tuberías, epolls, eventfds, timerfds, etc.
En cualquier momento durante el inicio del proceso, los límites pueden haber cambiado. Visite
/proc/<pid>/limits
y vea si los valores han sido alterados.fuente
@oligofren
También llevé a cabo algunas pruebas para determinar la forma
"ulimits -Sn"
de"open files"
fue aplicada.Al igual que el póster que Elegido mencionó en el enlace , el ulimit for
"open files"
se aplica por proceso. Para ver cuáles son los límites actuales del proceso:cat /proc/__process_id__/limits
Para determinar cuántos archivos tiene abierto un proceso, debe usar el siguiente comando:
lsof -P -M -l -n -d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt' -p __process_id__ -a | awk '{if (NR>1) print}' | wc -l
Explicación de lo anterior y mi método de prueba / resultados
Los
"-P -M -l -n"
argumentos de lsof simplemente están ahí para hacer que lsof funcione lo más rápido posible. Siéntase libre de sacarlos.El
"-d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt'"
argumento indicalsof
que se excluyan los descriptores de archivo de tipo: cwd / err / ltx / mem / mmap / pd / rtd / txt.Desde la página de manual de lsof:
Considero que
"Lnn,jld,m86,tr,v86"
no es aplicable a Linux y, por lo tanto, no me molesté en agregarlos a la lista de exclusión. No estoy seguro de eso"Mxx"
.Si sus aplicaciones utilizan marcas de archivos de memoria asignada / dispositivos a continuación, es posible que desee eliminar
"^mem"
y"^mmap"
de la lista de exclusión.EDITAR --- comenzar a cortar ---
Editar: encontré el siguiente enlace que indica que:
Entonces, si su proceso utiliza archivos asignados a la memoria, deberá filtrar los archivos * .so.
Además, JVM de Sun registrará archivos jar de mapas
Así que cosas como tomcat / glassfish también mostrarán archivos jar mapeados en memoria. No he probado si estos cuentan para el
"ulimit -Sn"
límite.EDITAR --- cortar final ---
Empíricamente, he encontrado que
"cwd,rtd,txt"
se no se cuenta con respecto al límite de archivo por proceso (ulimit Sn).No estoy seguro de si
"err,ltx,pd"
se cuentan para el límite de archivos, ya que no sé cómo crear identificadores de archivos de estos tipos de descriptores.El
"-p __process_id__"
argumento se limitalsof
a devolver solo información para lo__process_id__
especificado. Elimine esto si desea obtener un recuento de todos los procesos.El
"-a"
argumento se usa para AND las selecciones (es decir, los argumentos "-p" y "-d").La
"awk '{if (NR>1) print}'"
declaración se utiliza para omitir el encabezado que selsof
imprime en su salida.Probé usando el siguiente script perl:
Tuve que ejecutar el script en el depurador perl para asegurarme de que el script no terminara y lanzara los descriptores de archivo.
Ejecutar:
perl -d test.pl
En el depurador de perl, puede ejecutar el programa ingresando
c
y presionando enter y, siulimit -Sn
tiene un valor de 1024 , encontrará que el programa se detiene después de crear elTest1017.log
archivo/tmp
.Si ahora identifica el pid del proceso perl y usa el
lsof
comando anterior , verá que también genera 1024 .Elimine
"wc -l"
y reemplace con un"less"
para ver la lista de archivos que contaban hacia el límite de 1024 . Elimine también el"-d ^....."
argumento para ver que los descriptorescwd,txt
y no cuentan para el límite.rtd
Si ahora ejecuta
"ls -l /proc/__process_id__/fd/ | wc -l"
, verá un valor de 1025 devuelto. Esto se debe a quels
agregó un"total 0"
encabezado a su salida que se contó.Nota:
Para verificar si el sistema operativo se está quedando sin descriptores de archivo, es mejor comparar el valor de:
cat /proc/sys/fs/file-nr | awk '{print $1}'
con
cat /proc/sys/fs/file-max
https://www.kernel.org/doc/Documentation/sysctl/fs.txt documenta qué
file-nr
y quéfile-max
significa.fuente
Parece que su razonamiento es algo así como: "Tengo que reducir ese límite para no quedarme sin descriptores preciosos". La verdad es exactamente lo contrario: si su servidor se quedó sin descriptores de archivo, debe elevar ese límite de 1,024 a algo más grande. Para una
glassfish
implementación realista , 32,768 es razonable.Personalmente, siempre elevo el límite a alrededor de 8.192 en todo el sistema: 1.024 es simplemente ridículo. Pero querrás subir
glassfish
más alto. Compruebe/etc/security/limits.conf
. Puede agregar una entrada especial para que el usuario seglassfish
ejecute como.fuente
Desea echar un vistazo a los límites de todo el sistema establecidos en / proc / sys / fs / file-max y ajustarlo allí (hasta el próximo reinicio) o establecer fs.file-max en sysctl.conf para que sea permanente. Esto podría ser útil: http://www.randombugs.com/linux/tuning-file-descriptors-limits-on-linux.html
fuente
Error común al comparar el resultado de una llamada sin procesar con un supuesto límite.
Para el límite global (/ proc / sys / fs / file-max) debe echar un vistazo a / proc / sys / fs / file-nr -> el valor de puño indica lo que se utiliza y el último valor es el límite
El límite de OpenFile es para cada proceso, pero puede definirse en un usuario; consulte el comando "ulimit -Hn" para conocer los límites de usuario y consulte /etc/security/limits.conf para ver las definiciones. Generalmente se aplica con "usuario de la aplicación", por ejemplo: "tomcat": establezca el límite en 65000 para el usuario tomcat que se aplicará en el proceso de Java que ejecuta.
Si desea verificar el límite aplicado en un proceso, obtenga su PID y luego: cat / proc / $ {PID} / limits Si desea verificar cuántos archivos abre un proceso, obtenga su PID y luego: ls -1 / proc / {PID} / fd | wc -l (nota para ls es 'menos uno', no para confundir con 'menos el')
Si desea conocer detalles con lsof pero solo para aquellos que manejan archivos que cuentan para el límite, intente con estos: lsof -p $ {PID} | grep -P "^ (\ w + \ s +) {3} \ d + \ D +" lsof -p $ {PID} -d '^ cwd, ^ err, ^ ltx, ^ mem, ^ mmap, ^ pd, ^ rtd, ^ txt '-a
Observación: los 'archivos' son archivos / pipe / tcp connections / etc.
Tenga en cuenta que a veces probablemente necesite ser root o usar sudo para obtener el resultado correcto de los comandos, sin privilegio, a veces no tiene error, solo menos resultados.
y finalmente, si desea saber a qué 'archivos' en su sistema de archivos se accede mediante un proceso, eche un vistazo a: lsof -p {PID} | grep / | awk '{print $ 9}' | ordenar | uniq
que te diviertas !
fuente