Комментарии 2
жирная тема. а как лимиты настроили для процессов?
Двумя drop-in’ами к юниту, чтобы не трогать основной файл сервиса.
/etc/systemd/system/iwant-next.service.d/memory.conf:
[Service]
MemoryHigh=800M
MemoryMax=1G
Restart=always
/etc/systemd/system/iwant-next.service.d/perf.conf:
[Service]
Environment=MALLOC_ARENA_MAX=2
Environment=VIPS_CONCURRENCY=1
Разница между двумя лимитами тут принципиальна. MemoryHigh - мягкий: cgroup начинает давить на процесс и агрессивно отбирать память, но не убивает. MemoryMax - жёсткий потолок, за ним прилетает OOM внутри cgroup, и уже Restart=always поднимает сервис. То есть MemoryHigh стоит ниже намеренно: он тормозит рост до того, как дело дойдёт до убийства, и пользователь видит замедление, а не пятисотку.
Числа брал не из головы: под нагрузкой с правильными аренами RSS держится 300–430 МБ, так что 800 МБ - примерно двукратный запас, а 1 ГБ - граница, за которой на этой машине начинает страдать Postgres и соседние приложения (4 ГБ на всё).
Кстати, после перезапуска сервис под трафиком возвращается к самому MemoryHigh за пару минут и дальше живёт, упираясь в потолок. Это нормальное поведение cgroup - в лимит утрамбовывается в том числе то, что можно отдать под давлением. Поэтому «сидит на 800 МБ» здесь не означает «ему нужно 800 МБ».
И главное: лимиты - это страховка, а не лечение. Память перестала расти от MALLOC_ARENA_MAX=2, а не от них. Если поставить только лимиты, получите бесконечный цикл «раздулся - убили - поднялся».
Проверить, что применилось:
systemctl show iwant-next -p MemoryHigh -p MemoryMax -p Environment
systemctl status iwant-next # строка Memory: с пиком
А вы на чём сейчас упираетесь: в рост RSS или в OOM-килы?

Приложение течёт, а утечки нет: как оптимизатор картинок Next.js съел 4-гигабайтный VPS