Salutare tuturor. Am dat de o dilemă destul de serioasă pe un proiect cu vreo 12.000 de utilizatori activi. Clientul a început să prindă tracțiune și acum cere să trecem de pe o singură mașină babană de 16GB RAM la o arhitectură cu 3 servere de aplicație în spatele unui load balancer. Recunosc că, deși sunt pe backend de ceva ani, n-am mai configurat o astfel de infrastructură cap-coadă în producție și mă cam strânge spatele când mă gândesc la toate piesele în mișcare.
Până acum totul era simplu: monolit Node.js, baza de date PostgreSQL locală, fișierele salvate direct pe disc. Totul rula pe același VPS. Acum, planul meu inițial este să folosesc un Nginx ca load balancer (sau poate un AWS ALB, deși clientul vrea să evităm costurile de cloud pe cât posibil și să rămânem pe VPS-uri clasice). Însă, cu cât sap mai mult, cu atât dau de mai multe probleme de sincronizare.
Prima mare problemă sunt sesiunile utilizatorilor. În momentul de față, folosesc un memory store simplu în Node. Când voi avea trei servere, cererile aceluiași user vor fi distribuite aleatoriu. M-am gândit să introduc Redis pentru a stoca sesiunile centralizat. Dar vine întrebarea de rețea și latență: merită să pun Redis pe aceeași mașină cu baza de date sau să îl rulez pe o mașină separată? Dacă pică instanța unică de Redis, pică tot login-ul din aplicație. Am economisi probabil 30% din complexitate dacă am folosi sticky sessions din Nginx, dar asta anulează parțial beneficiul de load balancing dacă un server devine supraîncărcat.
A doua provocare este gestionarea conexiunilor la PostgreSQL. Fiecare instanță Node.js pornește un pool de conexiuni. Dacă trei servere deschid câte 30-40 de conexiuni active, o să ating rapid limita de max_connections din Postgres. Soluția standard pare să fie PgBouncer. Am înțeles că merge excelent pentru a refolosi conexiunile, dar vine cu un trade-off destul de mare: dacă îl configurez în modul transaction (care e cel mai eficient), pierd suportul pentru prepared statements. Folosesc Prisma ca ORM și știu că are ceva bătăi de cap cu PgBouncer în modul ăsta. A mai rulat cineva setup-ul ăsta în producție?
În final, rămâne problema fișierelor încărcate de utilizatori. Acum se salvează direct în /public/uploads. Pe trei servere diferite, dacă un user încarcă un avatar pe Serverul 1, Serverul 2 va returna 404 când va încerca să-l afișeze. S3 ar fi soluția clasică, dar din motive de GDPR și costuri, clientul vrea ceva self-hosted. Mă gândeam la un storage NFS partajat între cele trei noduri de aplicație, însă mi-e teamă de latența la scriere și de faptul că NFS devine un punct unic de eșec.
Cum ați aborda tranziția asta fără să vă complicați viața inutil din prima zi? Merită să pornesc direct cu Redis și PgBouncer, sau să merg pe varianta mai simplă cu sticky sessions și un singur VPS de DB supradimensionat până când chiar simțim nevoia de mai mult?