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

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

De Delia Petre, 18 iul. 2026 · 10 vizualizări · 3 like-uri

Postat 18 iul. 2026
bash
#!/bin/bash
URL="http://localhost:3000/healthz"
TIMEOUT=5
APP_NAME="my-api"

STATUS_CODE=$(curl --write-out "%{http_code}" --silent --output /dev/null --max-time $TIMEOUT "$URL")

if [ "$STATUS_CODE" -ne 200 ]; then
  echo "Healthcheck failed with status $STATUS_CODE. Reloading $APP_NAME..."
  pm2 reload "$APP_NAME"
else
  echo "App is healthy."
fi

PM2 e genul de instrument pe care îl arunci în producție și uiți de el până când totul crapă silențios. Am pățit de prea multe ori ca PM2 să raporteze statusul verde, „online”, în timp ce API-ul meu dădea timeout-uri pe bandă rulantă. În postarea asta îți arăt cum să faci un healthcheck real, care nu se lasă păcălit de un simplu proces activ în background.

De ce ne minte PM2?

PM2 monitorizează procesul la nivel de sistem de operare. Dacă procesul Node.js există în tabela de procese și consumă resurse, PM2 consideră că totul este în regulă. Însă Node.js are un singur thread principal. Dacă ai blocat Event Loop-ul cu o operațiune sincronă greoaie, aplicația ta devine complet inutilizabilă, deși procesul rulează tehnic.

La un proiect cu peste 14.000 de utilizatori activi, am avut o problemă cu un memory leak masiv. Garbage collector-ul rula continuu, CPU-ul era blocat la 100%, iar API-ul dădea erori 504. PM2 arăta vesel statusul „online” pentru că procesul nu crăpase fizic. Am pierdut conexiuni importante și ne-am alertat abia când ne-au scris clienții pe Slack. De atunci, am învățat că un ping HTTP local e sfânt.

Soluția: Healthcheck pe bune în aplicație

Ca să nu mai pățești asta, ai nevoie de un endpoint dedicat în aplicație (de exemplu, /healthz) și de un script extern care să-l apeleze periodic. Acest endpoint nu trebuie să returneze doar un text static de tip JSON chior. Trebuie să testeze minim două chestii critice:

  • O interogare simplă în baza de date (un SELECT 1 rapid ca să vezi că mai ai conexiuni disponibile în pool).
  • Event loop lag-ul (dacă e peste 200ms, serverul e deja înecat).

Trade-off-ul aici este destul de delicat și trebuie să fii atent la el. Dacă baza de date pică temporar pentru 5 secunde, iar healthcheck-ul tău dă restart la toate instanțele Node deodată, o să provoci un dezastru și mai mare. Când instanțele repornesc, vor bombarda din nou baza de date cu conexiuni noi la startup. De aceea, e bine să ai o marjă de eroare și să nu dai restart la prima eroare izolată, ci doar după 3 eșecuri consecutive.

Scriptul de monitorizare care chiar face treabă

În loc să te bazezi pe module PM2 obscure care adaugă overhead, poți folosi un script simplu de Bash rulat local prin cron la fiecare minut. Acesta dă un curl cu timeout strâns către endpoint-ul tău local. Dacă request-ul eșuează sau durează mai mult de 5 secunde, dăm un pm2 reload curat.

Un reload în PM2 face un restart secvențial (graceful), adică nu o să ai downtime deloc dacă ai configurat corect aplicația să ruleze în cluster mode cu minim două instanțe. Scriptul de mai jos salvează situația exact în momentele în care Node e complet blocat, dar sistemul de operare încă îl vede funcțional.

Voi cum gestionați blocajele astea de producție? Mergeți pe scripturi clasice sau ați mutat deja toată logica asta în liveness probes din Kubernetes?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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