systemd-oomd drepte langvarige sesjoner: ManagedOOMPreference=avoid og automatisk omstart

En langvarig tjeneste med aktive sesjoner forsvant midt i drift. Applikasjonen hadde ikke krasjet, og mine egne logger viste ingen feil. Prosessen var borte. Det tyder på minnepress og OOM-håndtering, så det var der jeg begynte å lete.
Bekreft årsaken i loggen

Sjekk først om det var systemd-oomd som drepte prosessen. Under minnepress går oomd gjennom cgroupene og dreper der presset er høyest, uavhengig av om kjernens OOM-killer har slått til.
journalctl -k --grep "Out of memory|oom-kill"Meldinger fra
journalctl -u systemd-oomd --since "-1h"
systemctl status systemd-oomdsystemd-oomd om at en cgroup ble drept, eller Killed process i kjerneloggen, bekrefter årsaken. Da kan du rette det presist i stedet for å endre grenser i blinde.
Høyere grenser flytter bare problemet
Å doble MemoryMax eller skru av swap-oppførselen utsetter problemet. Under ekte minnepress må noe fortsatt drepes, og uten instruksjon velger oomd selv. Det som løser det, er å fortelle systemd hvilke prosesser som kan ofres og hvilke som ikke kan det.
Marker hva som må overleve

systemd har en OOM-preferanse per unit. ManagedOOMPreference=avoid ber oomd nedprioritere denne cgroupen når et offer skal velges. Sett den på unit-en som holder de langvarige sesjonene.
[Service]Legg det i en drop-in, så overlever innstillingen pakkeoppgraderinger.
ManagedOOMPreference=avoid
systemctl edit min-tjeneste.serviceSjekk at preferansen ble lest inn:
# i editoren:
[Service]
ManagedOOMPreference=avoid
systemctl daemon-reload
systemctl restart min-tjeneste.service
systemctl show min-tjeneste.service -p ManagedOOMPreferenceMotsatt kan du sette ManagedOOMPreference=omit på batch-jobber og annet som kan ryke først. Da har oomd et bedre offer å velge enn et tilfeldig.
Kombiner med automatisk omstart
Preferansen er ingen garanti. Går minnet helt tomt, drepes noe uansett, så tjenesten må starte igjen av seg selv.
[Service]Har tjenesten sesjonstilstand, la den lese tilstanden fra disk ved oppstart, så aktive sesjoner tas opp igjen etter omstarten.
Restart=always
RestartSec=5
[Unit]
StartLimitIntervalSec=0


