Un load balancer è il punto che riceve richieste da client o sistemi intermedi e le inoltra verso più server backend secondo una logica definita. In pratica separa il nome pubblico del servizio dalla sua capacità reale di risposta, così puoi aggiungere, togliere o sostituire nodi senza cambiare l’endpoint visto dagli utenti.
La funzione non è solo “dividere il traffico”. Un bilanciatore serio fa anche da barriera operativa: controlla la salute dei backend, evita di mandare richieste a nodi guasti, può terminare TLS, applicare sticky session, filtrare connessioni anomale e, in alcuni casi, proteggere meglio il layer applicativo dagli spike di carico. Il punto chiave è questo: il load balancer non aumenta la potenza di un singolo server, ma distribuisce il rischio e sfrutta meglio l’insieme.
Perché serve davvero
In un’architettura con un solo server, il collo di bottiglia è ovvio: CPU, RAM, I/O disco, connessioni simultanee, timeout dell’applicazione. Con due o più backend, il problema cambia natura: devi decidere chi riceve cosa, quando e con quali criteri di esclusione. Qui entra il load balancer.
Gli obiettivi tipici sono tre:
- Disponibilità: se un nodo cade, il traffico va sugli altri.
- Scalabilità: puoi aggiungere backend per assorbire più richieste.
- Manutenibilità: fai deploy, patch o riavvii a rotazione senza fermare il servizio.
Nei sistemi web moderni il load balancer spesso è il primo elemento esposto su Internet. Questo significa che diventa anche il primo posto dove osservare sintomi come handshake lenti, 502/503, backend saturi o problemi di certificato. Se lo tratti come “scatola nera”, perdi metà della diagnosi.
Come decide dove mandare il traffico
Il comportamento del bilanciamento dipende dall’algoritmo. Non esiste un metodo migliore in assoluto: dipende dal tipo di carico, dalla durata delle connessioni e da quanto sono omogenei i backend.
- Round robin: invia le richieste in sequenza ai backend. È semplice e funziona bene quando i nodi sono simili e le richieste hanno peso comparabile.
- Least connections: privilegia il backend con meno connessioni attive. Utile quando le richieste hanno durata variabile, ad esempio API con tempi di elaborazione non uniformi.
- Weighted: assegna più traffico ai nodi più capaci. Serve quando i server non sono identici, per esempio mix di macchine con CPU diverse o pool eterogenei.
- Hash su client o request: manda la richiesta allo stesso backend in base a un valore deterministico, come IP sorgente, cookie o header. È spesso usato per mantenere la coerenza di sessione, ma va valutato bene perché può creare squilibri.
La scelta dell’algoritmo non va fatta a sensazione. Se hai richieste brevi e numerose, round robin può bastare. Se hai upload, stream, long polling o API lente, il least connections tende a distribuire meglio la pressione reale. Se invece il servizio richiede affinità di sessione, un hash o una sticky session possono semplificare l’applicazione, ma spostano complessità nell’infrastruttura.
Tipi di load balancer per livello
La distinzione più utile, in ambiente server, è quella per livello di rete. Qui cambia il tipo di informazione disponibile e quindi il tipo di decisione che il bilanciatore può prendere.
Layer 4: bilanciamento a livello trasporto
Un load balancer di Layer 4 lavora su IP, porta e protocollo di trasporto, quindi su TCP e UDP. Non interpreta il contenuto HTTP: vede una connessione e decide dove inoltrarla. È veloce, ha meno overhead e si presta bene a servizi generici, database proxy, TLS passthrough e applicazioni non HTTP.
Vantaggi principali: latenza ridotta, configurazione relativamente lineare, minor consumo di risorse. Limite principale: non conosce URL, header o cookie, quindi non può fare routing applicativo fine. Se devi mandare `/api` a un pool e `/static` a un altro, il Layer 4 non basta.
Scenario tipico: un servizio TCP con più istanze dietro un VIP. Il bilanciatore accetta la connessione e la inoltra a un backend sano, senza “capire” cosa passa nel flusso.
Layer 7: bilanciamento applicativo
Il Layer 7 lavora a livello HTTP/HTTPS e legge il contenuto della richiesta. Può decidere in base a host, path, header, cookie, metodo, query string e perfino regole più sofisticate. È il tipo più usato nei siti web, nelle API e nei cluster applicativi moderni.
Qui il bilanciatore può fare cose che un L4 non può: terminare TLS, riscrivere header, forzare redirect, applicare rate limit, separare backend per tenant o per versione dell’API. In cambio aggiunge complessità, perché il livello applicativo va mantenuto coerente con i comportamenti attesi dell’applicazione.
Esempio pratico: un dominio unico espone sia frontend sia API. Con regole L7 puoi mandare il traffico verso pool diversi in base al path:
location /api/ -> backend_api_pool
location / -> backend_web_poolIn ambienti reali questo approccio è utile anche per migrazioni graduali: una percentuale di traffico può essere deviata verso una nuova release senza cambiare DNS o IP pubblico.
DNS load balancing
Il bilanciamento via DNS è il più semplice da capire e il più facile da sopravvalutare. Il resolver restituisce più record A o AAAA, spesso con rotazione o pesi. Il client sceglie uno degli indirizzi. Funziona, ma con limiti evidenti: caching dei resolver, TTL, comportamento del client, assenza di health check in tempo reale.
È utile come prima forma di distribuzione geografica o come meccanismo di fallback grossolano. Non è la scelta migliore se vuoi failover immediato o controllo fine della sessione. Se un record punta a un nodo morto, il DNS non se ne accorge da solo. Per questo, in produzione, il DNS load balancing viene spesso affiancato da sistemi di monitoraggio e aggiornamento automatico dei record.
Load balancer hardware e software
La distinzione hardware/software oggi è meno netta di un tempo, ma resta utile. Un bilanciatore hardware è un appliance dedicato, spesso con accelerazione per TLS e grandi volumi di connessioni. Un bilanciatore software gira su server generici o come servizio cloud gestito.
Il software ha un vantaggio chiaro: flessibilità. Puoi integrarlo con IaC, aggiornare regole rapidamente, automatizzare health check e versionare la configurazione. L’hardware ha senso quando servono throughput elevati, latenza prevedibile, funzioni enterprise specifiche o integrazione con infrastrutture già standardizzate su appliance.
Funzioni che fanno la differenza in produzione
Quando un bilanciatore è usato sul serio, le funzioni importanti non sono quelle “da brochure”, ma quelle che evitano incidenti o rendono il troubleshooting più corto.
- Health check: il load balancer verifica se il backend risponde. Può essere un semplice TCP connect, un HTTP GET su una URL di stato o un controllo più articolato con codice atteso e contenuto minimo.
- Failover automatico: se un nodo smette di rispondere, viene escluso dal pool.
- Session persistence: richieste dello stesso utente verso lo stesso backend, quando serve affinità.
- TLS termination: il bilanciatore decifra il traffico e presenta un certificato pubblico unico.
- Rate limiting e protezioni base: riduzione dell’impatto di burst, abuso o client mal configurati.
- Observability: log, metriche di backend up/down, tempi di risposta, queue e errori 5xx.
Il punto più delicato è l’health check. Un check troppo banale può dichiarare sano un backend che in realtà è degradato. Un check troppo pesante può diventare esso stesso carico inutile. La regola pratica è testare il servizio minimo utile: non solo “la porta è aperta”, ma “l’app risponde con un contenuto coerente e il backend dipendente è disponibile se richiesto”.
Sticky session: utile, ma da non usare per inerzia
La sticky session, o session persistence, fa sì che un client venga mandato sempre allo stesso backend per un certo periodo. È comoda quando l’applicazione conserva stato in memoria locale e non è ancora stata resa stateless.
Il problema è che la sticky session nasconde un difetto architetturale: se il backend “preferito” degrada, il carico non si redistribuisce in modo realmente uniforme. Inoltre complica il dimensionamento, perché il traffico non è più perfettamente fungibile tra i nodi. In un ambiente ben progettato, lo stato di sessione dovrebbe vivere fuori dal singolo server: Redis, database, cache condivisa o token firmati lato client, a seconda del caso.
Usa la persistenza solo quando hai un motivo concreto, e considera sempre il costo operativo: più facilità per l’app oggi, più rigidità domani.
Bilanciamento e TLS: dove terminare la cifratura
Uno dei punti più discussi è la terminazione TLS. Puoi cifrare fino al bilanciatore e poi inoltrare in chiaro ai backend, oppure fare re-encryption verso i server interni, oppure usare passthrough.
- TLS termination al load balancer: semplifica certificati e offload della CPU. È la scelta più comune per web e API interne affidabili.
- TLS re-encryption: il bilanciatore decifra e ricifra verso i backend. Aumenta la protezione sul tratto interno.
- TLS passthrough: il bilanciatore non vede il contenuto cifrato. Utile se il backend deve gestire direttamente il certificato o se vuoi mantenere end-to-end senza ispezione applicativa.
La scelta dipende dal modello di fiducia interno. Se la rete backend è considerata affidabile e segmentata, terminare al bilanciatore è spesso sufficiente. Se invece vuoi difesa più robusta tra segmenti o audit più stretto, meglio ricifrare o mantenere il passthrough, sapendo però che perdi parte delle funzioni L7.
Un esempio pratico con Nginx come bilanciatore L7
Nginx è spesso usato come reverse proxy e load balancer leggero. Non sostituisce tutti i prodotti dedicati, ma per molti contesti è più che sufficiente.
Una configurazione minima può distribuire richieste tra tre backend HTTP:
upstream app_pool {
least_conn;
server 10.0.0.11:8080 max_fails=3 fail_timeout=10s;
server 10.0.0.12:8080 max_fails=3 fail_timeout=10s;
server 10.0.0.13:8080 max_fails=3 fail_timeout=10s;
}
server {
listen 443 ssl http2;
server_name example.com;
location / {
proxy_pass http://app_pool;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Questa configurazione mostra tre aspetti importanti. Primo: il bilanciamento è separato dal backend, che resta raggiungibile solo sulla rete privata. Secondo: gli header forwarded servono all’app per ricostruire contesto e log corretti. Terzo: i parametri di failover evitano di martellare un nodo instabile.
Se vuoi verificare che il bilanciamento stia funzionando, non limitarti a fare un singolo curl. Esegui più richieste e osserva la distribuzione, per esempio con un header custom inserito dal backend o con i log accesso.
for i in $(seq 1 10); do curl -sk https://example.com/ | grep -E 'backend|hostname'; doneIn mancanza di un’identificazione nel body, puoi usare un header diagnostico temporaneo lato backend, ma va rimosso in produzione se espone dettagli inutili.
Cloud load balancer: cosa cambia rispetto al self-hosted
Nei cloud pubblici il load balancer è spesso un servizio gestito. Il vantaggio è evidente: meno manutenzione dell’infrastruttura di front door, integrazione con autoscaling, health check nativi, spesso anche supporto per certificati gestiti e IPv4/IPv6 pubblici. Il rovescio della medaglia è il lock-in operativo e, in alcuni casi, una minore trasparenza su alcuni dettagli di routing o timeouts.
In un ambiente gestito devi guardare con attenzione almeno tre parametri: timeout di idle connection, modalità di health check e compatibilità con il protocollo applicativo. Errori classici: backend che chiude connessioni troppo presto, upload lunghi interrotti dal timeout, WebSocket mal configurati, header forwarded non gestiti correttamente.
La regola pratica è semplice: prima di mettere in produzione, prova il comportamento con un client reale e con una richiesta lenta, non solo con un semplice GET. Molti problemi emergono solo quando la connessione resta aperta abbastanza a lungo da attraversare i timeout di default.
Come scegliere il tipo giusto
La scelta migliore dipende dal traffico, dal livello di controllo richiesto e da quanto vuoi far capire al bilanciatore del tuo protocollo.
- Scegli Layer 4 se ti serve velocità, protocollo generico, passthrough o bilanciamento semplice a basso overhead.
- Scegli Layer 7 se il routing dipende da host, path, header, cookie o vuoi funzioni applicative come TLS termination e rate limiting.
- Scegli DNS se vuoi distribuzione grossolana o geografica e accetti i limiti del caching e del failover non immediato.
- Scegli un servizio cloud gestito se preferisci ridurre la gestione dell’infrastruttura e accetti il vincolo del provider.
In molti casi la risposta concreta è una combinazione: DNS per il livello esterno, load balancer L7 per il routing applicativo, proxy interni L4 per servizi non HTTP, e backend scalati orizzontalmente dietro tutto il resto. La vera architettura non è “un load balancer”, ma una catena di punti di decisione con responsabilità chiare.
Errori comuni che vedo spesso
- Usare sticky session per nascondere stato locale invece di progettare il servizio stateless.
- Fare health check troppo deboli, che dichiarano sano un backend già degradato.
- Terminare TLS senza aggiornare correttamente gli header forwarded nell’applicazione.
- Ignorare i timeout tra LB e backend, con sintomi che sembrano casuali ma non lo sono.
- Bilanciare su nodi eterogenei senza pesi, creando hotspot prevedibili.
- Non osservare i log del bilanciatore, poi cercare il problema solo nei log applicativi.
Il motivo per cui questi errori si ripetono è quasi sempre lo stesso: il load balancer viene considerato un componente di passaggio, mentre in realtà è un punto di controllo critico. Se lo configuri male, non solo non aiuta, ma può amplificare il guasto rendendolo più difficile da diagnosticare.
Osservabilità minima da tenere sempre attiva
Se gestisci un load balancer in produzione, tieni almeno questi segnali sotto controllo:
- numero di backend sani e non sani;
- errori 5xx generati dal bilanciatore;
- latenza verso i backend;
- connessioni attive e nuove connessioni al secondo;
- timeout di upstream e reset di connessione;
- distribuzione del traffico per backend.
Una dashboard utile deve dirti subito se il problema è nel DNS, nel bilanciatore, nel backend o nel database. Se vedi solo grafici generici di CPU, sei ancora troppo a valle della diagnosi.
Regola pratica finale
Un load balancer ben progettato non è un semplice “devia traffico”, ma un controllo di ingresso che decide disponibilità, routing e resilienza. Se il tuo servizio cresce, il bilanciatore smette di essere opzionale e diventa parte dell’architettura quanto l’applicazione stessa. La domanda giusta non è se usarlo, ma quale livello di bilanciamento ti serve davvero e quale stato vuoi far vivere al di fuori dei singoli nodi.
Se vuoi evitare sorprese, progetta il servizio come se un backend potesse sparire in qualsiasi momento. Se il bilanciatore riesce a gestire quel caso senza impatto visibile, allora stai facendo load balancing nel modo corretto.
Commenti (0)
Nessun commento ancora.
Segnala contenuto
Elimina commento
Eliminare definitivamente questo commento?
L'azione non si può annullare.