Too many open files: wenn einem Dienst die Dateideskriptoren ausgehen

Der Server hat freien Speicher und Plattenplatz, doch der Dienst fällt aus. So prüfen Sie Dateideskriptoren, tatsächliche Prozesslimits und den steigenden Verbrauch.

Ein Telekommunikationsmessgerät, das über ein gelbes Glasfaserkabel mit Netzwerktechnik in einem Rack verbunden ist
Fotografie: Ildefonso Polo / Unsplash

Eine Website nimmt einen Teil der Anfragen nicht mehr an, und im Log erscheint Too many open files. Der freie Plattenplatz sieht weiterhin unauffällig aus. Der Fehlername lässt an viele Dokumente denken, doch Deskriptoren werden auch für Sockets und Pipes verwendet. Eine neue Netzwerkverbindung benötigt ebenfalls einen Deskriptor. Diese Anleitung behandelt Linux; die Konfigurationsbeispiele setzen einen direkt von systemd gestarteten Dienst voraus.

Ermitteln Sie den genauen Fehler und den meldenden Prozess

Beim Öffnen einer Datei bezeichnet EMFILE das ausgeschöpfte Deskriptorlimit eines Prozesses. ENFILE bedeutet, dass das systemweite Limit offener Dateien erreicht wurde. Prüfen Sie diesen Unterschied in den Fehlerdetails. Derselbe Eingriff muss nicht beide Fälle lösen. Erfassen Sie Zeitpunkt, PID, Dienstname und fehlgeschlagenen Vorgang; der Text aus der Benutzeroberfläche allein kann ein wesentliches Detail auslassen.

Bei einem von systemd gestarteten Dienst liefert systemctl show --property=MainPID web.service die Kennung des Hauptprozesses. web.service ist ein beispielhafter Unit-Name. Bearbeiten Worker die Anfragen, ermitteln Sie auch den konkret betroffenen Prozess. Verwenden Sie beim Lesen von /proc eine PID im selben PID-Namensraum. Die Ausgabe eines anderen Prozesses oder einer neuen Instanz nach einem Neustart ersetzt keine Beobachtung des ursprünglichen Vorfalls.

Lesen Sie die Limits des laufenden Prozesses

Verwenden Sie cat /proc/PID/limits und ersetzen Sie PID durch die tatsächliche Kennung. Vergleichen Sie in der Zeile Max open files das Soft- und Hard-Limit. Das Soft-Limit wird durchgesetzt; das Hard-Limit bildet seine Obergrenze für einen unprivilegierten Prozess. Notieren Sie beide mit dem Beobachtungszeitpunkt. Ein hohes Hard-Limit bestätigt kein ebenso hohes aktuell verwendetes Soft-Limit.

ulimit -n in einer administrativen Shell beschreibt deren eigenen Kontext. Kindprozesse erben Limits bei ihrer Erzeugung; diese bleiben auch über execve() erhalten. Eine Änderung in diesem Terminal passt einen bereits laufenden Dienst daher nicht rückwirkend an. Prüfen Sie bei mehreren Prozessen die betroffenen PIDs einzeln. Ändert die Anwendung eigene Limits, vergleichen Sie die Startkonfiguration mit dem tatsächlichen Zustand nach der Initialisierung.

Verfolgen Sie, was Deskriptoren offen hält

ls -l /proc/PID/fd zeigt nach Deskriptornummer benannte Einträge und deren symbolische Links. Bei Sockets und Pipes enthalten die Links auch Typ und Inode. Berechtigungen können den Zugriff einschränken; fehlender Zugriff bedeutet keinen Verbrauch von null. Begrenzen Sie weitergegebene Angaben, weil Pfadnamen die interne Struktur des Dienstes offenlegen können.

Vergleichen Sie wiederholte Aufnahmen bei ähnlicher Last und nach Abschluss der Arbeit. Eine steigende Anzahl kann durch mehr Parallelität, einen absichtlich gehaltenen Pool oder fehlende Ressourcenfreigabe entstehen. Eine einzelne Aufnahme beweist kein Leck. Prüfen Sie in der Anwendung die Freigabe von Dateien und Verbindungen auch bei Fehlern oder abgebrochenen Vorgängen. close() gibt einen Deskriptor zur Wiederverwendung frei; verwalten Sie Ressourcen über die Mechanismen der jeweiligen Laufzeitumgebung.

Prüfen Sie die Limitänderung zusammen mit dem Anwendungsverhalten

Für einen direkt von systemd gestarteten Dienst konfiguriert LimitNOFILE= das Limit; ein Paar soft:hard setzt beide Werte getrennt. Prüfen Sie vor einer Erhöhung die Anwendungskompatibilität: select() unter Linux kann Deskriptoren über 1023 nicht verarbeiten. Bestimmen Sie die benötigte Reserve anhand von Parallelität und Messungen. Ein höheres Limit kann eine sinnvolle Kapazitätsänderung sein, erklärt aber keinen Verbrauch, der ohne erwarteten Grund weiter steigt.

systemctl daemon-reload allein lädt die Managerkonfiguration neu und startet den Dienst nicht neu. Planen Sie die Änderung deshalb passend zu dessen Startverfahren und Verfügbarkeit. Prüfen Sie nach einem kontrollierten Neustart /proc/PID/limits der neuen Prozesse und wiederholen Sie den zuvor fehlgeschlagenen Vorgang unter vergleichbarer Last. Beobachten Sie Fehler und Deskriptorverlauf. Richten Sie Warnungen nach der Reserve bis zum durchgesetzten Limit aus; erweitern Sie bei ENFILE die Untersuchung auf den gesamten Host.

  • Unterscheiden Sie EMFILE und ENFILE und ermitteln Sie die richtige PID.
  • Prüfen Sie Soft- und Hard-Limit des laufenden Prozesses.
  • Vergleichen Sie den Verbrauch unter Last und nach Abschluss der Arbeit.
  • Wiederholen Sie nach der Änderung den Vorgang und verfolgen Sie die Entwicklung.

Was Sie mitnehmen

Beginnen Sie bei Too many open files mit dem konkreten Prozess und seinen tatsächlichen Limits. Messen Sie, was er offen hält, und unterscheiden Sie erwartete Parallelität von Fehlern in der Ressourcenverwaltung. Bestätigen Sie die Reparatur durch einen abgeschlossenen Benutzervorgang und stabiles Verhalten unter entsprechender Last.

Dokumentation und weiterführende Links

Mgr. Martin Hlavaj, MBA

Softwareentwickler

Alle Artikel

Erfahren Sie frühzeitig von Ausfällen.

Fügen Sie Ihre Website oder API zu UpBot hinzu und bestimmen Sie, wer den Alarm erhält.

Kostenlos überwachen