Tutoriel Linux

Ulimit onder Linux: een limiet van bestanden signaleren voordat een service uitvalt

Débutant3 min de lecture

Een service die plotseling nieuwe verbindingen weigert of “Too many open files” schrijft, heeft misschien geen geheugenprobleem. Het kan zijn limiet van file descriptors hebben bereikt. Onder Linux verbruikt een socket, een log, een bestand en soms een pipe een file descriptor.

De opdracht ulimit -n toont de limiet van de huidige shell. Het bewijst niet de limiet van de reeds gestart service. Voor een daemon beheerd door systemd, controleer het proces, de eenheid en de persistente configuratie voordat je iets verandert.

Tux voor servers met mappen en connectoren die een limiet op Linux-bestanden vertegenwoordigen
De limieten van open bestanden moeten op proces- en systemd-niveau worden gecontroleerd.

Lees de limiet van de shell en die van het proces

In je terminal, begin met het onderscheiden van de zachte limiet van de harde limiet. De eerste kan door een proces worden verlaagd. De tweede stelt het plafond vast dat een niet-geprivilegieerde gebruiker niet kan overschrijden.

ulimit -Sn
ulimit -Hn

Een resultaat van 1024 kan voldoende zijn voor een interactieve sessie. Het wordt snel te kort voor een proxy, een webserver of een applicatie die veel open verbindingen behoudt. Kopieer geen waarde die je op een forum hebt gevonden: begin met meten wat de service gebruikt.

Vind zijn PID, lees vervolgens de werkelijk toegepaste limieten :

systemctl show nginx -p MainPID
sudo grep 'Max open files' /proc/1234/limits
sudo ls /proc/1234/fd | wc -l

Vervang 1234 door de door systemd geretourneerde PID. De teller in /proc/1234/fd geeft een momentopname van het aantal open file descriptors. Vergelijk het met Max open files. Een kleine afwijking verklaart beter een verzadiging dan een simpele indruk van traagheid.

Controleer de systemd-limiet voordat je deze wijzigt

Een systemd-service haalt niet automatisch de waarde van je SSH-sessie op. De eenheid kan LimitNOFILE definiëren, of erft een globale waarde. Toon de effectieve waarde :

systemctl show nginx -p LimitNOFILE
systemctl cat nginx

Als de eenheid een lage limiet toont en de logs bevestigen openingfouten, maak dan een override in plaats van het door het pakket verstrekte bestand te wijzigen :

sudo systemctl edit nginx

Voeg vervolgens deze sectie toe, met een waarde die is afgestemd op je applicatie :

[Service]
LimitNOFILE=65535

Voor een service die in productie wordt blootgesteld, houd een tweede SSH-sessie open. Een fout in de eenheid of een mislukte herstart mag je niet zonder toegang laten. Controleer ook de documentatie van de applicatie: sommige leggen hun eigen plafond op, die verschilt van systemd.

Herstart en controleer de werkelijk toegepaste waarde

Na de override, herlaad de configuratie en herstart de enige betrokken service :

sudo systemctl daemon-reload
sudo systemctl restart nginx
systemctl show nginx -p LimitNOFILE
systemctl status nginx --no-pager

Lees ten slotte /proc/PID/limits opnieuw met de nieuwe PID. Als LimitNOFILE gelijk is aan 65535 in systemd, maar het proces blijft op 1024, kijk je waarschijnlijk naar een oude PID, een andere service of een tussenliggende supervisor.

De controles die je moet uitvoeren voordat je de limiet verhoogt

  • Bevestig de exacte fout in journalctl -u nginx of in de applicatielogs.
  • Meet het aantal open file descriptors voor en na een piekbelasting.
  • Verhoog de limiet voor een specifieke eenheid, niet voor alle services op de machine.
  • Monitor de verbindingen, bestanden en sockets die open blijven: een lek van file descriptors moet in de applicatie worden opgelost.

Een hogere limiet voorkomt een abrupte stop van een service, maar herstelt geen proces dat bestanden opent zonder ze te sluiten. Houd de waargenomen waarden en logfragmenten bij: ze zullen helpen beslissen of de limiet te laag was of dat de service moet worden gecorrigeerd.

sudo apt update && sudo apt upgrade