Salutare tuturor. Am intrat într-o belea destul de mare, dar din aia din care înveți: un client cu o aplicație PHP/Laravel destul de mărișoară (avem în jur de 15.000 de useri activi pe zi) vrea să trecem de la clasicul „un singur VPS mare” la o arhitectură pe trei servere în spatele unui load balancer. Problema e simplă: nu am mai făcut asta cap-coadă în producție și recunosc că am un pic de morcov.
După două zile de documentare intensă, am realizat că nu load balancer-ul în sine e problema cea mai mare (probabil o să folosesc un Cloudflare sau un load balancer administrat de la provider), ci modul în care aplicația împarte resursele. Am identificat trei puncte critice unde mi se poate bloca totul în gât.
1. Sesiunile și cache-ul (Redis)
În momentul de față, sesiunile utilizatorilor sunt salvate pe disc, local. Dacă pun un load balancer în față, chiar și cu sticky sessions activate, mi se pare o bombă cu ceas. Dacă pică serverul 1, toți userii de pe el sunt delogați când ajung pe serverul 2.
Soluția logică e să mut totul în Redis. Dar unde pun Redis-ul? Îl pun pe un server separat sau îl las pe unul dintre cele trei servere de aplicație? Am făcut un mic test de latență și dacă pun Redis pe o mașină separată, în același datacenter, am o latență de vreo 1.2ms. Pare mică, dar la 100 de query-uri de cache pe request se simte. Trade-off-ul e clar: securitate și consistență contra performanță brută.
2. Fișierele uploadate (Coșmarul S3)
Aici am dat de cea mai mare barieră. Utilizatorii încarcă PDF-uri și imagini destul de des. Acum ele se salvează în /public/uploads. Pe trei servere diferite, dacă un user încarcă o factură pe serverul A, cel de pe serverul B va primi o eroare 404 când încearcă să o descarce.
Am două opțiuni și ambele au bube. Prima: montez un volum NFS partajat pe toate cele trei mașini. E cel mai simplu de implementat, nu modific codul deloc. Totuși, am citit că NFS-ul devine incredibil de lent când ai multe operațiuni de I/O concurente. A doua opțiune: mut totul pe AWS S3 sau DigitalOcean Spaces. Asta e varianta curată, dar mă costă vreo 3-4 zile de refactoring în codul vechi de 5 ani, unde drumul către fișiere e hardcodat în zeci de locuri.
3. Conexiunile la baza de date
Folosim PostgreSQL. În prezent are cam 80 de conexiuni active simultan. Dacă pun trei servere de aplicație, fiecare cu pool-ul lui de conexiuni, mă tem că o să îngenunchez baza de date foarte repede, mai ales la spike-uri de trafic.
Aici cred că am nevoie de un manager de conexiuni gen PgBouncer. L-aș pune direct pe serverul de bază de date ca să facă pooling. A mai folosit cineva PgBouncer în producție reală pentru un volum de genul ăsta? Îmi simplifică viața sau adaugă un nou layer de complexitate unde pot apărea erori ciudate de protocol?
Cum ați aborda voi tranziția asta dacă ați fi în locul meu? Ați face totul dintr-o dată sau ați muta mai întâi baza de date pe un server dedicat, apoi fișierele pe S3 și abia la final ați pune load balancer-ul?