eduardweb.
PM2 & NodeIntermediar#nodejs#devops#pm2#javascript

Cum configurezi PM2 ca un senior: cluster mode, graceful reload și protecție la OOM

De Cosmin Rotaru, 19 iul. 2026 · 8 vizualizări · 3 like-uri

Postat 19 iul. 2026
javascript
module.exports = {
  apps: [
    {
      name: 'api-prod',
      script: './dist/index.js',
      instances: 'max',
      exec_mode: 'cluster',
      autorestart: true,
      max_memory_restart: '1G',
      kill_timeout: 5000,
      env_production: {
        NODE_ENV: 'production',
        PORT: 3000
      }
    }
  ]
};

Mi-a luat ceva timp să înțeleg că un simplu pm2 start index.js e o bombă cu ceas în producție. Acum vreo trei ani, la un proiect cu peste 15k utilizatori activi, ne-am trezit cu SSD-ul plin din cauza logurilor și cu downtime de câteva secunde bune la fiecare deploy. Atunci am decis să trec totul pe ecosystem.config.js și am rezolvat 90% din problemele de instabilitate.

Dacă încă rulezi aplicațiile Node.js fără un fișier de configurare dedicat, pierzi controlul asupra proceselor tale când serverul intră sub presiune.

Cluster mode și zero-downtime pe bune

Dacă ai un VPS cu 4 sau 8 nuclee, e păcat să rulezi Node.js pe un singur fir de execuție. Cu instances: 'max' și exec_mode: 'cluster', PM2 pornește automat câte o instanță pentru fiecare core disponibil. Dar aici apare o mare capcană.

Mulți developeri dau pm2 restart all la deploy. Asta omoară toate procesele instant și taie conexiunile clienților în mijlocul tranzacțiilor. Soluția corectă este pm2 reload.

Pentru ca reload-ul să fie cu adevărat "graceful" (fără downtime), trebuie să îi spui aplicației tale să își închidă conexiunile la baza de date curat înainte de a se opri. PM2 trimite un semnal SIGINT procesului vechi, apoi așteaptă să pornească cel nou. Dacă în codul tău nu asculți de acest semnal, PM2 va omorî procesul brutal după expirarea kill_timeout (care implicit e destul de mică, recomand să o urci la 5000ms).

OOM (Out of Memory) și logurile care ucid serverul

Node.js are prostul obicei să acumuleze memorie dacă ai memory leak-uri în cod sau prin librării terțe. Am pățit ca o librărie de generare PDF-uri să urce RAM-ul la 1.8GB în doar câteva ore, blocând tot serverul.

Prin adăugarea proprietății max_memory_restart: '1G', PM2 monitorizează constant consumul. Când procesul trece de 1GB, îi dă un restart curat în fundal. Nu îți rezolvă bug-ul de memorie, dar îți ține producția în picioare până apuci să faci debugging.

O altă problemă majoră sunt logurile scrise în ~/.pm2/logs/. Fără o rotație a logurilor, te trezești sâmbăta la 4 dimineața că baza de date nu mai poate scrie nimic pentru că disk-ul e 100% plin. Deși poți configura pm2-logrotate global din CLI, prefer să am totul documentat în repository-ul proiectului printr-un script de bootstrap sau instrucțiuni clare pentru echipa de sysadmini.

Trade-off-uri de care trebuie să știi

Cluster mode e excelent, dar vine cu un cost de arhitectură. Sesiunile stocate în memorie (in-memory sessions) devin complet inutile pentru că request-urile utilizatorului vor fi distribuite aleatoriu între procese diferite. Va trebui să muți sesiunile în Redis.

De asemenea, dacă ai joburi de tip Cron rulate direct în Node.js, acestea se vor executa de atâtea ori câte instanțe ai pornite în cluster. Pentru a evita asta, recomand să izolezi cron-urile într-un proces separat, rulat pe o singură instanță (non-cluster).

Voi cum gestionați procesele de Node în producție? Mergeți pe PM2 pe mașini virtuale clasice sau ați migrat complet spre Docker și Kubernetes?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.