eduardweb.
DevOps & VPSIntermediar#nodejs#devops#pm2#monitoring

Healthcheck care chiar funcționează pentru PM2 — ce scapă și ce prinde

De Cosmin Rotaru, 26 mai 2026 · 5 vizualizări · 2 like-uri

Postat 26 mai 2026
javascript
const express = require('express');
const app = express();

let dbConnected = true; // Actualizat de driverul de DB
let lastEventLoopTick = Date.now();

// Monitorizăm dacă event loop-ul este blocat
setInterval(() => {
  lastEventLoopTick = Date.now();
}, 1000);

app.get('/healthz', async (req, res) => {
  const lag = Date.now() - lastEventLoopTick;
  
  // Dacă event loop-ul e blocat de mai mult de 5 secunde
  if (lag > 5000) {
    return res.status(503).send({ status: 'unhealthy', reason: 'Event loop lag too high' });
  }

  if (!dbConnected) {
    return res.status(503).send({ status: 'unhealthy', reason: 'DB connection down' });
  }

  res.send({ status: 'healthy', lag });
});

Am trecut cu toții prin asta: te uiți în pm2 list, vezi frumos verde, status „online”, dar clienții urlă pe Slack că site-ul e jos. Am pățit-o acum doi ani la un proiect cu vreo 12k useri activi pe oră. PM2 zicea că totul e brici, dar event loop-ul era atât de blocat de un query prost încât Node nu mai procesa nicio cerere HTTP.

De ce ne minte PM2?

PM2 face o singură chestie de bază excelent: se asigură că procesul tău de Node rulează în sistemul de operare. Dacă procesul are un PID activ, pentru PM2 înseamnă că e „online”.

Dar în realitate, aplicația ta poate fi un zombie. Poate că baza de date a picat, pool-ul de conexiuni e epuizat, sau ai un memory leak masiv care a înghețat event loop-ul înainte ca OOM (Out Of Memory) killer-ul să apuce să trimită semnalul de kill. În toate aceste cazuri, procesul există, deci PM2 nu va da restart automat.

Soluția: Healthcheck activ, nu pasiv

Ca să dormi liniștit noaptea, ai nevoie de un endpoint de /healthz în aplicație care să testeze pe bune dacă sistemul e funcțional.

Dar atenție la un trade-off major aici. Dacă pui load balancer-ul (sau un script local) să apeleze endpoint-ul ăsta la fiecare 5 secunde și tu interoghezi baza de date de fiecare dată direct, s-ar putea să-ți încarci baza degeaba. Am pățit să avem 5% din CPU-ul bazei de date consumat doar de ping-urile de healthcheck de la cele 4 instanțe de microservicii.

Am rezolvat problema asta cache-uind rezultatul verificărilor grele (bază de date, Redis) timp de 15 secunde. Endpoint-ul returnează instant statusul salvat în memorie, evitând astfel un DDOS auto-provocat.

Cum legăm asta de monitorizare?

Dacă rulezi în AWS sau în spatele unui Nginx local, pui load balancer-ul să facă polling pe /healthz. Dacă pică de 3 ori la rând, scoate instanța din uz.

Pentru un VPS simplu unde PM2 rulează „pe curat”, poți folosi un script de cron care dă un simplu curl local o dată pe minut. Dacă primești status non-200 sau timeout, rulezi un pm2 reload <app_name>. E o soluție puțin brutală, dar pe noi ne-a salvat de la downtime de zeci de minute în miezul nopții.

Voi cum gestionați procesele zombie în PM2? Vă bazați doar pe restart-delay sau aveți un watchdog extern?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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