Notre serveur a récemment manqué de descripteurs de fichiers, et à ce sujet, j'ai quelques questions. ulimit -n
est censé me donner le nombre maximum de descripteurs de fichiers ouverts. Ce nombre est 1024. J'ai vérifié le nombre de descripteurs de fichiers ouverts en exécutant lsof -u root |wc -l
et j'ai obtenu 2500 fds. C'est beaucoup plus que 1024, donc je suppose que cela signifierait que le nombre 1024 est par processus, pas par utilisateur, comme je le pensais. Eh bien, j'ai couru lsof -p$PidOfGlassfish|wc -l
et obtenu 1300. C'est la partie que je ne reçois pas. Si ce ulimit -n
n'est pas le nombre maximum de processus par utilisateur ou par processus, à quoi sert-il? Ne s'applique-t-il pas à l'utilisateur root? Et si oui, comment pourrais-je alors obtenir les messages d'erreur sur le manque de descripteur de fichier?
EDIT: La seule façon dont je peux avoir un sens ulimit -n
est d'appliquer le nombre de fichiers ouverts (comme indiqué dans le manuel bash) plutôt que le nombre de descripteurs de fichiers (différents processus peuvent ouvrir le même fichier). Si tel est le cas, alors simplement lister le nombre de fichiers ouverts (grepping sur '/', excluant ainsi les fichiers mappés en mémoire) ne suffit pas :
lsof -u root |grep /|sort -k9 |wc -l #prints '1738'
Pour voir réellement le nombre de fichiers ouverts, je devrais filtrer sur la colonne de nom pour imprimer uniquement les entrées uniques. Ainsi, ce qui suit est probablement plus correct:
lsof -u root |grep /|sort -k9 -u |wc -l #prints '604'
La commande ci-dessus attend une sortie au format suivant à partir 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
Cela me donne au moins un nombre inférieur à 1024 (le nombre rapporté par ulimit -n
), donc cela semble être un pas dans la bonne direction. "Malheureusement", je n'ai aucun problème avec le manque de descripteurs de fichiers, j'ai donc du mal à le valider.
la source
Réponses:
J'ai testé cela dans la version Linux 2.6.18-164.el5 - Red Hat 4.1.2-46. J'ai pu voir que l'ulimit est appliqué par processus.
Le paramètre est défini au niveau de l'utilisateur, mais appliqué à chaque processus.
Par exemple: 1024 était la limite. Plusieurs processus ont été démarrés et les fichiers ouverts par chacun ont été comptés à l'aide de
Il n'y a eu aucune erreur lorsque la somme des fichiers ouverts par plusieurs processus a dépassé 1024. J'ai également vérifié le nombre de fichiers uniques combinant les résultats pour différents processus et comptant les fichiers uniques. Les erreurs ont commencé à apparaître uniquement lorsque le nombre de chaque processus a dépassé 1024. (java.net.SocketException: trop de fichiers ouverts dans les journaux de processus)
la source
lsof -p$PidOfGlassfish|wc -l
m'a donné 1300? Je suppose que les deux approches du comptage diffèrent en quelque sorte. Sinon, alors peut-être que la limite ne s'applique pas à l'utilisateur root?ls -l
au lieu dels
? Ce dernier a une ligne supplémentaire (par exempletotal 5
) lorsqu'il y a 5 fichiers. Dans un tel cas, l'utilisationls -l
dans l'exemple ci-dessus rapporterait 6 et non 5. J'utilisels /proc/<pid>/fd | wc -l
.ls -l
me donne une entrée par ligne, que je redirige ensuite vers autre chose. Bien sûr, cela se produit également lorsque la tuyauterie est normalels
(mais non autrement).L'ulimit est pour les descripteurs de fichiers. Il s'applique aux fichiers, répertoires, sockets, epolls de tuyaux, eventfds, timerfds etc. etc.
À tout moment pendant le démarrage des processus, les limites peuvent avoir été modifiées. Visitez
/proc/<pid>/limits
et voyez si les valeurs ont été modifiées.la source
@oligofren
J'ai également effectué des tests afin de déterminer comment
"ulimits -Sn"
pour"open files"
a été appliquée.Comme l'affiche Chosen mentionnée dans le lien , l'ulimit pour
"open files"
est en effet appliqué par processus. Pour voir quelles sont les limites actuelles du processus:cat /proc/__process_id__/limits
Pour déterminer le nombre de fichiers ouverts par un processus, vous devez utiliser la commande suivante:
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
Explication de ce qui précède et de ma méthode / résultats de test
Les
"-P -M -l -n"
arguments de lsof sont simplement là pour faire fonctionner lsof le plus rapidement possible. N'hésitez pas à les retirer.L'
"-d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt'"
argument indiquelsof
d'exclure les descripteurs de fichiers de type: cwd / err / ltx / mem / mmap / pd / rtd / txt.Depuis la page de manuel lsof:
J'ai considéré
"Lnn,jld,m86,tr,v86"
comme non applicable à Linux et je n'ai donc pas pris la peine de les ajouter à la liste d'exclusion. Je n'en suis pas sûr"Mxx"
.Si votre application utilise des fichiers / périphériques mappés en mémoire, vous souhaiterez peut-être les supprimer
"^mem"
et"^mmap"
les exclure de la liste.MODIFIER --- commencer le snip ---
Edit: j'ai trouvé le lien suivant qui indique que:
Donc, si votre processus utilise des fichiers mappés en mémoire, vous devrez filtrer les fichiers * .so.
De plus, la JVM de Sun va mapper en mémoire les fichiers jar
Ainsi, des choses comme tomcat / glassfish afficheront également des fichiers jar mappés en mémoire. Je n'ai pas testé si ceux-ci comptent pour la
"ulimit -Sn"
limite.EDIT --- fin de capture ---
Empiriquement, j'ai trouvé que
"cwd,rtd,txt"
sont pas pris en compte en ce qui concerne la limite par fichier de processus (ulimit -Sn).Je ne sais pas s'ils
"err,ltx,pd"
sont pris en compte dans la limite de fichiers car je ne sais pas comment créer des descripteurs de fichiers de ces types de descripteurs.L'
"-p __process_id__"
argument se limitelsof
à renvoyer uniquement des informations pour le__process_id__
spécifié. Supprimez-le si vous souhaitez obtenir un compte pour tous les processus.L'
"-a"
argument est utilisé pour ET les sélections (c'est-à-dire les arguments "-p" et "-d").L'
"awk '{if (NR>1) print}'"
instruction est utilisée pour ignorer l'en-tête quilsof
s'imprime dans sa sortie.J'ai testé en utilisant le script perl suivant:
J'ai dû exécuter le script dans le débogueur perl pour m'assurer que le script ne se termine pas et libérer les descripteurs de fichiers.
Éxécuter:
perl -d test.pl
Dans le débogueur de Perl, vous pouvez exécuter le programme en entrant
c
et en appuyant sur Entrée et si votreulimit -Sn
valeur était 1024 , vous constaterez que le programme s'arrête après la création duTest1017.log
fichier dans/tmp
.Si vous identifiez maintenant le pid du processus perl et utilisez la
lsof
commande ci-dessus, vous verrez qu'il génère également 1024 .Supprimez le
"wc -l"
et remplacez-le par un"less"
pour voir la liste des fichiers comptés pour la limite de 1024 . Supprimez également l'"-d ^....."
argument pour voir que les descripteurscwd,txt
et ne comptent pas dans la limite.rtd
Si vous exécutez maintenant
"ls -l /proc/__process_id__/fd/ | wc -l"
, vous verrez une valeur de 1025 retournée. En effet,ls
un en-"total 0"
tête a été ajouté à sa sortie qui a été compté.Remarque:
Pour vérifier si le système d'exploitation manque de descripteurs de fichiers, il est préférable de comparer la valeur de:
cat /proc/sys/fs/file-nr | awk '{print $1}'
avec
cat /proc/sys/fs/file-max
https://www.kernel.org/doc/Documentation/sysctl/fs.txt documente ce
file-nr
quefile-max
signifie et signifie.la source
Il semble que votre raisonnement soit quelque chose comme "Je dois abaisser cette limite pour ne pas manquer de précieux descripteurs". La vérité est exactement l'inverse - si votre serveur n'a plus de descripteurs de fichiers, vous devez augmenter cette limite de 1 024 à quelque chose de plus grand. Pour une
glassfish
mise en œuvre réaliste , 32 768 est raisonnable.Personnellement, j'augmente toujours la limite à environ 8 192 à l'échelle du système - 1 024 est tout simplement ridicule. Mais vous voudrez augmenter
glassfish
plus haut. Vérifiez/etc/security/limits.conf
. Vous pouvez ajouter une entrée spéciale pour l'utilisateurglassfish
s'exécute en tant que.la source
Vous voulez jeter un œil aux limites à l'échelle du système définies dans / proc / sys / fs / file-max et les ajuster là (jusqu'au prochain redémarrage) ou définir fs.file-max dans sysctl.conf pour le rendre permanent. Cela pourrait être utile - http://www.randombugs.com/linux/tuning-file-descriptors-limits-on-linux.html
la source
Erreur courante pour comparer le résultat de l'appel lsof brut avec la limite supposée.
Pour la limite globale (/ proc / sys / fs / file-max), vous devriez jeter un œil à / proc / sys / fs / file-nr -> la première valeur indique ce qui est utilisé et la dernière valeur est la limite
La limite OpenFile est pour chaque processus mais peut être définie sur un utilisateur, voir la commande "ulimit -Hn" pour les limites utilisateur et voir /etc/security/limits.conf pour les définitions. Généralement appliqué avec "utilisateur d'application", par exemple: "tomcat": définissez la limite à 65000 pour l'utilisateur tomcat qui s'appliquera lors du processus java qu'il exécute.
Si vous voulez vérifier la limite appliquée sur un processus, obtenez son PID puis: cat / proc / $ {PID} / limits Si vous voulez vérifier combien de fichiers sont ouverts par un processus, obtenez son PID puis: ls -1 / proc / {PID} / fd | wc -l (note pour ls c'est 'moins un', ne pas confondre avec 'moins el')
Si vous voulez connaître les détails avec lsof mais uniquement pour les gestionnaires de fichiers qui comptent pour la limite, essayez avec ceux-ci: lsof -p $ {PID} | grep -P "^ (\ w + \ s +) {3} \ d + \ D +" lsof -p $ {PID} -d '^ cwd, ^ err, ^ ltx, ^ mem, ^ mmap, ^ pd, ^ rtd, ^ txt '-a
Remarque: les 'fichiers' sont des fichiers / connexions pipe / tcp / etc.
Notez que parfois vous devrez probablement être root ou utiliser sudo pour obtenir le résultat correct pour les commandes, sans privilège parfois vous n'avez pas d'erreur, juste moins de résultats.
et enfin si vous voulez savoir à quels «fichiers» de votre système de fichiers un processus accède, consultez: lsof -p {PID} | grep / | awk '{print $ 9}' | trier | uniq
s'amuser !
la source