Webová služba, která zpomaluje, pracovník zabit bez jasné zprávy nebo server, který přepíná, nemusí nutně využívat veškerou RAM stroje. S systemd může být limit nastavený na jednotku dostatečný k vysvětlení symptomu.
Cgroups umožňují jádru Linuxu počítat, omezovat a priorizovat zdroje skupiny procesů. Než přidáte paměť nebo náhodně restartujete, zkontrolujte, co systemd aplikuje na dotčenou službu.

Zobrazit cgroup služby
Na nedávných distribucích systemd umisťuje každou službu do jejího vlastního cgroup. Nemusíte ručně přesouvat PID, abyste diagnostikovali klasickou jednotku jako Nginx, PostgreSQL nebo aplikačního pracovníka.
Začněte čtením stavu služby a vlastností souvisejících se zdroji. Nahraďte nginx.service skutečným názvem vaší jednotky.
systemctl status nginx.service --no-pager
systemctl show nginx.service -p ControlGroup -p MainPID -p MemoryCurrent -p MemoryMax -p MemoryHigh -p CPUQuotaPerSecUSec
ControlGroup dává cestu řízenou systemd. MemoryCurrent zobrazuje paměť započítanou pro jednotku v okamžiku čtení. Pokud MemoryMax je infinity, systemd nenastavil tvrdý paměťový strop pro tuto službu.
Pokud vycházíte z PID, přečtěte si jeho cgroup ze /proc. Ve cgroup v2 často uvidíte řádek typu 0::/system.slice/nginx.service.
pid=$(systemctl show nginx.service -p MainPID --value)
cat /proc/$pid/cgroup
Pokud MainPID je 0, služba nemá žádný aktivní hlavní proces. Vraťte se k systemctl status a journalctl, místo abyste usuzovali na základě prázdného PID.
Číst limity paměti a CPU
MemoryMax je tvrdý limit. Pokud cgroup dosáhne tohoto stropu a jádro nezíská dostatek paměti, může být proces ve skupině zabit OOM killerem.
MemoryHigh je méně drastický. Jádro zpomaluje alokace a snaží se uvolnit paměť, když cgroup překročí tento práh. Aby bylo možné udržet službu bez jejího zhroucení při prvním vrcholu, je často lepší prvotní nastavení než MemoryMax.
CPUQuota omezuje dostupný čas CPU pro službu. CPUQuota=25% dává ekvivalent čtvrtinového logického jádra. Na stroji s více jádry CPUQuota=200% povoluje až dvě jádra CPU času.
systemctl show nginx.service
-p MemoryCurrent -p MemoryMax -p MemoryHigh
-p CPUUsageNSec -p CPUQuotaPerSecUSec
Nespojujte kvótu a prioritu. Kvóta brání službě překročit množství CPU. Priorita, s nice nebo CPUWeight, spíše rozhoduje o konkurenci, když více úloh žádá o CPU současně.
Najít zdroj limitu
Limit může pocházet z konfiguračního souboru dodaného balíčkem, z drop-in systemd nebo z místního přepsání. Přečtěte si celou konfiguraci, než upravíte službu.
systemctl cat nginx.service
systemctl show nginx.service -p FragmentPath -p DropInPaths
Soubor pod /etc/systemd/system/nginx.service.d/ obvykle přebírá kontrolu nad jednotkou dodanou balíčkem. Vyhněte se přímému upravování souboru v /usr/lib/systemd/system/ nebo /lib/systemd/system/, protože aktualizace jej mohou přepsat.
Poté zkontrolujte symptomy. Zpomalená služba může také pocházet z pomalého SQL dotazu, saturace disku, plné fronty nebo aplikační chyby.
journalctl -u nginx.service -b --no-pager
journalctl -k -b | grep -Ei 'oom|out of memory|killed process|memory cgroup'
Pokud limity zůstávají na infinity a jádrový žurnál neukazuje žádné události paměti, hledejte jinde, než se dotknete cgroups: aplikační logy, metriky disku, síťová latence nebo skutečná spotřeba procesu.
Testovat bez dotyku služby
Pro ověření syntaxe nebo měření efektu limitu spusťte dočasnou jednotku pomocí systemd-run. Test nemění Nginx, PostgreSQL nebo vaši obchodní službu.
sudo systemd-run --unit=essai-limite-memoire
--property=MemoryMax=256M
--property=CPUQuota=25%
/usr/bin/bash -c 'sleep 300'
Poté si přečtěte aplikované vlastnosti. Pro CPUQuota=25% může systemd zobrazit hodnotu ekvivalentní 250ms za sekundu.
systemctl show essai-limite-memoire.service
-p MemoryMax -p CPUQuotaPerSecUSec -p ControlGroup -p ActiveState
systemctl cat essai-limite-memoire.service
Jakmile dokončíte, zastavte testovací jednotku. S sleep není zapomenutí tragické, ale tento reflex zabraňuje překvapením, když test spouští skutečný příkaz.
sudo systemctl stop essai-limite-memoire.service
Použití přepsání systemd
Když žurnály a měření potvrzují, že limit dává smysl, přejděte k přepsání systémem systemd. Příklad níže nastavuje vysokou hranici na 800 MB, tvrdý strop na 1 GB a omezuje službu na ekvivalent jednoho CPU jádra.
sudo systemctl edit mon-service.service
Přidejte pouze nezbytné direktivy. Nekopírujte tyto hodnoty na produkční službu, aniž byste sledovali její normální spotřebu a vrcholy.
[Service]
MemoryHigh=800M
MemoryMax=1G
CPUQuota=100%
Načtěte znovu systemd a restartujte službu pouze pokud je to přerušení přijatelné. Na dálku si nechte otevřenou druhou relaci SSH, když se dotýkáte kritické komponenty.
sudo systemctl daemon-reload
sudo systemctl restart mon-service.service
systemctl status mon-service.service --no-pager
systemctl show mon-service.service -p MemoryCurrent -p MemoryHigh -p MemoryMax -p CPUQuotaPerSecUSec
Pokud se služba nespustí nebo se stane příliš pomalou, opatrně odstraňte přepsání. sudo systemctl revert mon-service.service odstraní místní přepsání jednotky. Nepoužívejte to, pokud stejný adresář obsahuje další nastavení, která chcete uchovat.
Kontroly po změně
- Zkontrolujte stav pomocí
systemctl is-active mon-service.service. - Přečtěte si
MemoryCurrent,MemoryHigh,MemoryMaxaCPUQuotaPerSecUSecpo restartu. - Sledujte
journalctl -u mon-service.service -ba jádrové žurnály během problému zatížení. - Změřte efekt na aplikační straně: doba odezvy, opožděné úkoly, fronty, chyby uživatele.
- Poznamenejte důvod nastavení, datum, přijatou hodnotu a opravený symptom do své provozní dokumentace.
Cgroups chrání zbytek stroje a činí limity viditelnými. Neopravují únik paměti, příliš nákladný dotaz nebo špatně dimenzovaného pracovníka. Pokud je strop dosažen, uchovejte žurnál, pozorované zatížení a nakonfigurovanou hodnotu, abyste se rozhodli mezi úpravou limitu a opravou aplikace.
Pro hlubší porozumění stránka systemd.resource-control(5) podrobně popisuje každou direktivu. Průvodce Nice pod Linuxem pomáhá vybrat prioritu CPU, když striktní strop není vhodný.