Hai un sito che scala male e il server singolo va in affanno quando arriva una promozione o un picco di visite? Magari hai già aggiunto più server, ma il traffico si accumula su uno solo mentre gli altri restano quasi inattivi. È il problema classico di chi non ha configurato un bilanciamento del carico, o lo ha fatto con le impostazioni sbagliate.
Noi, di Meteora Web, ci occupiamo di server da anni — anche di quelli che tengono in piedi e-commerce con centinaia di ordini al giorno. Quando un cliente ci dice «il sito va lento dopo le 10 di mattina», la prima cosa che controlliamo è se il load balancing è configurato correttamente. E spesso scopriamo che si usa il metodo sbagliato per il tipo di applicazione.
In questa guida vedremo i tre metodi di bilanciamento più usati su Nginx: round robin, least connections e ip-hash. Non ci limiteremo a spiegare la sintassi: ti diremo quando usarli, perché funzionano e — soprattutto — quali errori evitare per non ritrovarti con un server sovraccarico e clienti persi.
Round Robin, Least Connections e IP-Hash: Come Funzionano e Quando Convengono?
Partiamo dalla base. Nginx supporta diversi algoritmi di load balancing. I tre più comuni, e quelli che devi conoscere per il 90% dei casi, sono:
- Round Robin: distribuisce le richieste in sequenza, una dopo l'altra, a ogni server del gruppo.
- Least Connections: invia la richiesta al server con il minor numero di connessioni attive in quel momento.
- IP-Hash: associa ogni indirizzo IP del client a un server specifico, usando una funzione di hash.
La scelta dipende dalla natura della tua applicazione. Un semplice blog statico o un sito vetrina può andare benissimo con round robin. Un'applicazione web con sessioni utente memorizzate localmente (sessione PHP su file, per esempio) ha bisogno di ip-hash o di un backend condiviso (Redis). Un'API che gestisce carichi di lavoro asimmetrici — dove alcune richieste richiedono molto più tempo di altre — beneficia di least connections.
Sponsored Protocol
Noi abbiamo visto progetti in cui un round robin su server con capacità diverse produceva colli di bottiglia: il server più potente veniva saturato perché capitava in turno mentre gli altri restavano a metà carico. È un errore da principianti, ma capita più spesso di quanto si creda.
Round Robin: il default da non sottovalutare
È il metodo predefinito di Nginx. Non serve scrivere nulla di speciale: se definisci un upstream senza direttive di bilanciamento, ottieni round robin. Esempio minimo:
upstream backend {
server web1.example.com;
server web2.example.com;
server web3.example.com;
}
Funziona bene quando tutti i server hanno la stessa potenza e le richieste hanno tempi di risposta simili. Svantaggio: non tiene conto del carico attuale. Se una richiesta su web1 impiega 10 secondi (perché fa un'elaborazione pesante), e subito dopo arriva un'altra richiesta, Nginx la manda comunque a web1 anche se è già impegnata.
Quando usarlo: per carichi omogenei, server identici, applicazioni stateless (API REST stateless, file server, proxy per CDN).
Sponsored Protocol
Least Connections: intelligente ma non sempre la scelta giusta
Con least connections, Nginx tiene traccia del numero di connessioni attive su ogni server. Invia la nuova richiesta a quello con il minor numero. Ideale per applicazioni con carichi di lavoro variabili.
upstream backend {
least_conn;
server web1.example.com;
server web2.example.com;
server web3.example.com;
}
Attenzione: le connessioni attive non equivalgono al carico CPU o memoria. Un server può avere poche connessioni ma ognuna molto pesante. In pratica, però, per la maggior parte delle applicazioni web PHP/Node/Python, least_conn funziona meglio di round robin quando i tempi di risposta non sono uniformi.
Errore comune: abbinare least_conn a keepalive scarso. Se il client mantiene connessioni persistenti (HTTP/1.1, HTTP/2), il conteggio delle connessioni attive può restare alto anche su server con poco carico effettivo. Noi consigliamo di monitorare il numero di connessioni attive e di usare keepalive con parsimonia se le app hanno picchi di connessioni contemporanee.
IP-Hash: quando la sessione non può essere condivisa
L'ip-hash garantisce che uno stesso client (stesso indirizzo IP) venga sempre reindirizzato allo stesso server. È essenziale per applicazioni che salvano lo stato della sessione in locale (file di sessione PHP su disco, ad esempio) senza un backend centralizzato come Redis o Memcached.
upstream backend {
ip_hash;
server web1.example.com;
server web2.example.com;
server web3.example.com;
}
Nginx calcola un hash dell'indirizzo IP del client e lo mappa su uno dei server. Se un server viene rimosso (mark down), le sue richieste vengono redistribuite, ma poi l'hash non cambia per i server rimanenti. Nota: se usi un proxy o un CDN, l'IP del client potrebbe essere quello del proxy, rompendo la persistenza. In quel caso dovresti usare hash $http_x_forwarded_for o un cookie di sessione.
Sponsored Protocol
Quando usarlo: solo se non puoi centralizzare le sessioni. Noi di Meteora Web abbiamo clienti che ancora non hanno migrato a una soluzione di sessioni condivise (Redis su server separato). In quei casi ip-hash è una soluzione pragmatica, ma non è la migliore a lungo termine. La vera risposta è possedere il proprio stack e centralizzare le sessioni, eliminando la dipendenza dall'IP del client.
Come Configurare Nginx per il Load Balancing con Pesi e Backup
Ogni metodo può essere combinato con pesi (weight) per distribuire il carico in modo non uniforme, e con server di backup (backup) che entrano in gioco solo quando i primari sono offline.
upstream backend {
least_conn;
server web1.example.com weight=3;
server web2.example.com weight=1;
server web3.example.com backup;
}
Qui web1 riceve tre volte più traffico di web2 (perché è più potente), e web3 è di riserva. Il backup è fondamentale per avere alta affidabilità senza pagare server sempre accesi. Noi lo usiamo per i nostri progetti: un server secondario più piccolo gestisce il failover, e i clienti non si accorgono nemmeno del cambio.
Sponsored Protocol
Quale Algoritmo Scegliere per un E-commerce o un'App PHP?
Dipende dallo stato delle sessioni. Se hai già centralizzato le sessioni su Redis (e dovresti), least_conn è la scelta migliore per carichi variabili. Se invece sei ancora con sessioni su file, ip_hash è inevitabile, ma pianifica la migrazione a un backend condiviso il prima possibile.
Un errore che vediamo spesso: usare round robin con server di diversa potenza senza pesi. Il server più debole si satura, il più forte resta sottoutilizzato. Aggiungi i pesi subito.
Per un'API REST stateless (JWT, nessuna sessione server-side), round robin è perfetto e più semplice. Per un'applicazione WebSocket, usa ip_hash o sticky sessions con cookie.
Errori Comuni nel Load Balancing Nginx e Come Evitarli
- Non impostare
max_failsefail_timeout: se un server va giù, Nginx continua a mandargli richieste e le fa fallire. Impostamax_fails=3 fail_timeout=30s. - Dimenticare
proxy_next_upstream: se il backend risponde con errore 500, Nginx non ritenta su un altro server a meno che non glielo dici. - Usare
keepalivesenza considerare le connessioni attive: con least_conn, le connessioni keepalive contano come connessioni attive e possono falsare la distribuzione. - Non testare il failover: ferma un server e verifica che le richieste vengano reindirizzate senza timeout. Noi lo facciamo sempre in fase di deploy.
upstream backend {
least_conn;
server web1.example.com max_fails=3 fail_timeout=30s;
server web2.example.com max_fails=3 fail_timeout=30s;
server web3.example.com backup;
}
location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Cosa Fare Adesso
- Controlla la tua configurazione attuale: se hai un upstream senza
least_connoip_hash, valuta se serve un cambio. Per carichi omogenei, round robin va bene. Per carichi variabili, passa a least_conn. - Aggiungi pesi e backup: se hai server con potenza diversa, usa
weight. Aggiungi un server di backup per la resilienza. - Centralizza le sessioni: se usi ip_hash solo per la persistenza della sessione, pianifica una migrazione a Redis. Leggi la nostra guida pillar su Nginx per approfondire la configurazione completa.
- Testa il failover: spegni un server e verifica che il traffico vada correttamente agli altri. Usa
curlo strumenti comeab(Apache Bench) per simulare carico. - Monitora le connessioni attive: con
nginx statuso Prometheus, tieni d'occhio il numero di connessioni per server. Se restano sbilanciate, rivedi la configurazione.
Il load balancing non è solo una questione di sintassi — è una scelta architetturale che impatta direttamente sulla velocità del sito e sulla soddisfazione degli utenti. Noi, di Meteora Web, lo trattiamo con la stessa attenzione che mettiamo nella contabilità di un'azienda: ogni decisione ha un costo e un ritorno. Sei pronto a ottimizzare il tuo?
Sponsored Protocol
Risorsa esterna: Documentazione ufficiale Nginx sul load balancing.