Если нужно аккуратно ограничить потребление памяти процессом, systemd делает это буквально из коробки. Причем не грубо, а с понятной логикой: можно замедлять процесс, забирать у него память или в крайнем случае прибивать. Все параметры описаны в документации, но на практике используются лишь несколько ключевых. Разберу их на примере.
▪️ Основные параметры
▪️
MemoryAccounting=yesВключает учет потребления памяти для юнита. Без этого остальные лимиты просто не работают.
▪️
MemoryHigh=2GМягкий лимит. Процесс может его превышать, но systemd начнет активно забирать память и тормозить выполнение. Основной и самый безопасный механизм.
▪️
MemoryMax=3GЖёсткий предел. При достижении процесс будет убит OOM Killer’ом. Использовать стоит осторожно, скорее как страховку.
▪️
MemorySwapMax=512MОграничение на использование swap. Полезно, если не хотите, чтобы сервис утонул в свопе.
▪️
Restart=on-failureПозволяет автоматически перезапустить сервис, если его убили по памяти.
▪️
OOMPolicy=killОпределяет поведение при OOM: либо корректная остановка (stop), либо жесткое убийство (kill).
▪️ Пример systemd unit
[Unit]
Description=Node.js Worker
After=network.target
[Service]
ExecStart=/usr/bin/node /opt/app/worker.js
Restart=on-failure
MemoryAccounting=yes
MemoryHigh=2G
MemoryMax=3G
MemorySwapMax=512M
OOMPolicy=kill
[Install]
WantedBy=multi-user.target
▪️ Быстрое тестирование из консоли. Создадим процесс, который пытается съесть 1 ГБ памяти:
node -e 'let a = "x".repeat(1024*1024*1024); setTimeout(()=>{}, 600000)'
Теперь запустим его с лимитами через systemd:
systemd-run --scope \
-p MemoryHigh=300M \
-p MemoryMax=400M \
node -e 'let a = "x".repeat(1024*1024*1024); setTimeout(()=>{}, 600000)'
Процесс запросит гигабайт, но реально получит лишь разрешенный объем.
Проверяем:
ps -o pid,rss,cmd -C node
RSS будет в пределах лимита, даже если виртуальная память (VSZ) гораздо больше.
#linux #systemd
🧑💻 NetworkAdmin