Unserem Server sind kürzlich die Dateideskriptoren ausgegangen, und diesbezüglich habe ich einige Fragen. ulimit -n
soll mir die maximale Anzahl offener Dateideskriptoren geben. Diese Nummer ist 1024. Ich habe die Anzahl der geöffneten Dateideskriptoren überprüft, indem ich ausgeführt habe lsof -u root |wc -l
und 2500 fds erhalten habe. Das ist viel mehr als 1024, also würde das bedeuten, dass die Zahl 1024 pro Prozess und nicht pro Benutzer ist, wie ich dachte. Nun, ich bin gelaufen lsof -p$PidOfGlassfish|wc -l
und habe 1300. Das ist der Teil, den ich nicht bekomme. Wenn ulimit -n
es nicht die maximale Anzahl von Prozessen pro Benutzer oder pro Prozess gibt, wofür ist es dann gut? Gilt das nicht für den Root-Benutzer? Und wenn ja, wie könnte ich dann die Fehlermeldungen erhalten, dass der Dateideskriptor ausgeht?
BEARBEITEN: Die einzige Möglichkeit, aus der ich einen Sinn ziehen kann, ulimit -n
besteht darin, die Anzahl der geöffneten Dateien (wie im Bash-Handbuch angegeben) anstelle der Anzahl der Dateizugriffsnummern anzuwenden (verschiedene Prozesse können dieselbe Datei öffnen). Wenn dies der Fall ist, dann Listing einfach die Anzahl der geöffneten Dateien (greppen auf ‚/‘, also ohne Speicherdateien abgebildet) ist nicht sufficent:
lsof -u root |grep /|sort -k9 |wc -l #prints '1738'
Um die Anzahl der geöffneten Dateien tatsächlich zu sehen, müsste ich nach der Namensspalte filtern, um nur die eindeutigen Einträge zu drucken. Daher ist das Folgende wahrscheinlich korrekter:
lsof -u root |grep /|sort -k9 -u |wc -l #prints '604'
Der obige Befehl erwartet die Ausgabe in folgendem Format von 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
Dies gibt mir zumindest eine Zahl von weniger als 1024 (die von gemeldete Zahl ulimit -n
), so dass dies ein Schritt in die richtige Richtung zu sein scheint. "Leider" habe ich keine Probleme damit, dass mir die Dateideskriptoren ausgehen. Daher werde ich es schwer haben, dies zu überprüfen.
quelle
Antworten:
Ich habe dies in Linux Version 2.6.18-164.el5 - Red Hat 4.1.2-46 getestet. Ich konnte sehen, dass das Ulimit pro Prozess angewendet wird.
Der Parameter wird auf Benutzerebene festgelegt, jedoch für jeden Prozess angewendet.
ZB: 1024 war das Limit. Es wurden mehrere Prozesse gestartet und die jeweils geöffneten Dateien mit gezählt
Es gab keine Fehler, als die Summe der von mehreren Prozessen geöffneten Dateien 1024 überschritt. Ich habe auch die Anzahl der eindeutigen Dateien überprüft, wobei die Ergebnisse für verschiedene Prozesse kombiniert und eindeutige Dateien gezählt wurden. Die Fehler traten nur auf, wenn die Anzahl der Prozesse 1024 überschritt. (Java.net.SocketException: Zu viele offene Dateien in Prozessprotokollen)
quelle
lsof -p$PidOfGlassfish|wc -l
ich 1300 bekommen habe? Ich vermute, die beiden Ansätze zum Zählen unterscheiden sich irgendwie. Wenn nicht, gilt das Limit möglicherweise nicht für den Root-Benutzer?ls -l
statt verwendenls
? Letzteres hat eine zusätzliche Zeile (zBtotal 5
), wenn es 5 Dateien gibt. In einem solchen Fall würde die Verwendungls -l
in dem obigen Beispiel 6 und nicht 5 melden. Ich verwendels /proc/<pid>/fd | wc -l
.ls -l
gebe mir einen Eintrag pro Zeile, den ich dann in etwas anderes pipe. Natürlich passiert dies auch bei normaler Verrohrungls
(aber nicht anders).Das ulimit ist für Dateihandles. Dies gilt für Dateien, Verzeichnisse, Sockets, Pipes, Epolls, Eventfds, Timerfds usw. usw.
Zu jedem Zeitpunkt während des Prozessstarts können sich die Grenzwerte geändert haben. Besuchen Sie
/proc/<pid>/limits
und prüfen Sie, ob die Werte geändert wurden.quelle
@oligofren
Ich habe auch einige Tests durchgeführt, um festzustellen, wie
"ulimits -Sn"
für"open files"
erzwungen wurde.Wie das im Link erwähnte Poster Chosen wird das ulimit for in der Tat pro Prozess angewendet. So ermitteln Sie die aktuellen Grenzen des Prozesses:
"open files"
cat /proc/__process_id__/limits
Um festzustellen, wie viele Dateien ein Prozess geöffnet hat, müssen Sie den folgenden Befehl verwenden:
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
Erklärung der oben genannten und meiner Testmethode / Ergebnisse
Die
"-P -M -l -n"
Argumente zu lsof sind einfach dazu da, lsof so schnell wie möglich arbeiten zu lassen. Fühlen Sie sich frei, sie herauszunehmen.Das
"-d '^cwd,^err,^ltx,^mem,^mmap,^pd,^rtd,^txt'"
Argument weistlsof
an, Dateideskriptoren des Typs auszuschließen: cwd / err / ltx / mem / mmap / pd / rtd / txt.Aus der Manpage von lsof:
Ich habe es
"Lnn,jld,m86,tr,v86"
als nicht zutreffend für Linux erachtet und habe mich daher nicht darum gekümmert, sie der Ausschlussliste hinzuzufügen. Da bin ich mir nicht sicher"Mxx"
.Wenn Ihre Anwendung mit Speicher verknüpfte Dateien / Geräte verwendet, möchten Sie möglicherweise
"^mem"
und"^mmap"
aus der Ausschlussliste entfernen .BEARBEITEN --- Snip starten ---
Bearbeiten: Ich habe den folgenden Link gefunden, der darauf hinweist, dass:
Wenn in Ihrem Prozess Speicherzuordnungsdateien verwendet werden, müssen Sie * .so-Dateien herausfiltern.
Die JVM von Sun speichert JAR-Dateien
Dinge wie Tomcat / Glassfish zeigen daher auch JAR-Dateien mit Speicherzuordnungen an. Ich habe nicht getestet, ob diese zum
"ulimit -Sn"
Limit zählen.BEARBEITEN --- Snip beenden ---
Empirisch habe ich festgestellt, dass
"cwd,rtd,txt"
im Hinblick auf das Pro-Prozess-Dateilimit (ulimit-Sn) nicht gezählt wird .Ich bin mir nicht sicher, ob diese
"err,ltx,pd"
auf das Dateilimit angerechnet werden, da ich nicht weiß, wie Dateizugriffsnummern dieser Deskriptortypen erstellt werden.Das
"-p __process_id__"
Argument beschränkt sich darauflsof
, nur Informationen für die__process_id__
angegebene zurückzugeben. Entfernen Sie diese Option, wenn Sie eine Zählung für alle Prozesse erhalten möchten.Das
"-a"
Argument wird zur UND-Verknüpfung der Auswahlen verwendet (dh die Argumente "-p" und "-d").Die
"awk '{if (NR>1) print}'"
Anweisung wird verwendet, um die Kopfzeile zu überspringen, dielsof
in der Ausgabe gedruckt wird.Ich habe mit dem folgenden Perl-Skript getestet:
Ich musste das Skript im Perl-Debugger ausführen, um sicherzustellen, dass das Skript nicht beendet und die Dateideskriptoren freigegeben werden.
Ausführen:
perl -d test.pl
Im Perl-Debugger können Sie das Programm ausführen, indem
c
Sie die Eingabetaste drücken. Wenn Sieulimit -Sn
den Wert 1024 hatten , wird das Programm nach dem Erstellen derTest1017.log
Datei in angehalten/tmp
.Wenn Sie jetzt die PID des Perl-Prozesses identifizieren und den obigen
lsof
Befehl verwenden, werden Sie sehen, dass er auch 1024 ausgibt .Entfernen Sie das Symbol
"wc -l"
und ersetzen Sie es durch ein Symbol"less"
, um die Liste der Dateien anzuzeigen, die bis zum Grenzwert von 1024 gezählt haben . Entfernen Sie auch das"-d ^....."
Argument, um zu sehen, dass diecwd,txt
undrtd
-Deskriptoren nicht zum Limit gezählt haben.Wenn Sie jetzt ausführen
"ls -l /proc/__process_id__/fd/ | wc -l"
, wird der Wert 1025 zurückgegeben. Dies liegt daran , dass der Ausgabels
ein"total 0"
Header hinzugefügt wurde , der gezählt wurde.Hinweis:
Um zu überprüfen, ob dem Betriebssystem die Dateideskriptoren ausgehen, ist es besser, den Wert von zu vergleichen :
cat /proc/sys/fs/file-nr | awk '{print $1}'
mit
cat /proc/sys/fs/file-max
https://www.kernel.org/doc/Documentation/sysctl/fs.txt dokumentiert, was
file-nr
und wasfile-max
bedeutet.quelle
Es scheint, als ob Ihre Argumentation so etwas wie "Ich muss diese Grenze senken, damit mir nicht die wertvollen Deskriptoren ausgehen". Die Wahrheit ist genau das Gegenteil: Wenn auf Ihrem Server keine Dateideskriptoren mehr verfügbar sind, müssen Sie diese Grenze von 1.024 auf etwas Größeres erhöhen . Für eine realistische
glassfish
Implementierung sind 32.768 sinnvoll.Persönlich erhöhe ich das Limit immer auf ungefähr 8.192 im gesamten System - 1.024 ist einfach lächerlich. Aber du wirst
glassfish
höher erhöhen wollen . Überprüfen Sie/etc/security/limits.conf
. Sie können einen speziellen Eintrag für den Benutzer hinzufügen,glassfish
der als ausgeführt wird.quelle
Sie möchten einen Blick auf die systemweiten Grenzwerte werfen, die in / proc / sys / fs / file-max festgelegt sind, und sie dort anpassen (bis zum nächsten Neustart) oder fs.file-max in sysctl.conf festlegen, um sie dauerhaft zu machen. Dies könnte hilfreich sein - http://www.randombugs.com/linux/tuning-file-descriptors-limits-on-linux.html
quelle
Häufiger Fehler beim Vergleichen des Ergebnisses von Raw-Lsof-Aufrufen mit dem angenommenen Limit.
Für das globale Limit (/ proc / sys / fs / file-max) sollten Sie sich / proc / sys / fs / file-nr ansehen -> der erste Wert gibt an, was verwendet wird und der letzte Wert ist das Limit
Das OpenFile-Limit gilt für jeden Prozess, kann jedoch für einen Benutzer definiert werden. Die Benutzerlimits finden Sie unter "ulimit -Hn" und die Definitionen unter /etc/security/limits.conf. Wird im Allgemeinen mit "app user" angewendet, z. B .: "tomcat": Setzen Sie das Limit auf 65000 für den Benutzer tomcat, der auf den von ihm ausgeführten Java-Prozess angewendet wird.
Wenn Sie die auf einen Prozess angewendete Begrenzung überprüfen möchten, ermitteln Sie die PID und dann: cat / proc / $ {PID} / limits Wenn Sie überprüfen möchten, wie viele Dateien von einem Prozess geöffnet werden, ermitteln Sie die PID und dann: ls -1 / proc / {PID} / fd | wc -l (Anmerkung für ls ist es 'minus eins', nicht mit 'minus el' zu verwechseln)
Wenn Sie Details mit lsof wissen möchten, aber nur für die Datei-Handler, die für das Limit zählen, probieren Sie Folgendes aus: lsof -p $ {PID} | grep -P "^ (\ w + \ s +) {3} \ d + \ D +" lsof -p $ {PID} -d '^ cwd, ^ err, ^ ltx, ^ mem, ^ mmap, ^ pd, ^ rtd, ^ txt '-a
Bemerkung: die 'files' sind files / pipe / tcp connections / etc.
Beachten Sie, dass Sie manchmal wahrscheinlich root sein müssen oder sudo verwenden müssen, um ein korrektes Ergebnis für die Befehle zu erhalten. Manchmal haben Sie ohne Berechtigung keinen Fehler, nur weniger Ergebnisse.
Und wenn Sie wissen möchten, auf welche 'Dateien' in Ihrem Dateisystem ein Prozess zugreift, schauen Sie sich Folgendes an: lsof -p {PID} | grep / | awk '{print $ 9}' | sortieren | uniq
habe Spaß !
quelle