Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Configurazione: load balancer HTTP

Il bilanciamento del carico (load balancing) di un'applicazione ottimizza l'uso delle risorse di un server: ecco come configurare nginx a tale scopo.
Il bilanciamento del carico (load balancing) di un'applicazione ottimizza l'uso delle risorse di un server: ecco come configurare nginx a tale scopo.
Link copiato negli appunti

Il bilanciamento del carico di un'applicazione su più istanze della stessa è una tecnica comunemente utilizzata per ottimizzare l'utilizzo delle risorse, massimizzare il throughput, ridurre la latenza di risposta e garantire una certa resilienza in caso di guasti. Il principio di funzionamento consiste nel far pervenire tutte le richieste ad un unico server, il quale provvede a distribuirle ai vari application server che compongono l'infrastruttura, agendo di fatto da reverse proxy.

Le modalità con le quali il server individua l'application server al quale redirigere le richieste dipendono dalla configurazione.

Nginx può essere configurato per svolgere il ruolo di load balancer in modo molto efficiente. In particolare, nginx supporta tre differenti modalità di load balancing:

  • round-robin - Le richieste vengono distribuite in sequenza ciclica, in base all'ordine di arrivo;
  • least-connected - Ogni richiesta è assegnata al server con meno connessioni attive in quel momento;
  • ip-hash - Una funzione di hashing è utilizzata come funzione di mappatura tra l'indirizzo IP del client e l'identificativo del server che gestirà la richiesta.

Configurazione

Nel caso più semplice, la configurazione è simile a quella già vista per un reverse proxy, con l'aggiunta della direttiva upstream. La direttiva upstream viene utilizzata per indicare gli indirizzi degli application server utilizzati dal reverse proxy.

Ad esempio, supponendo di voler gestire le richieste in arrivo su www.miaapp.com attraverso i server srv1.miaapp.com, srv2.miaapp.com, srv3.miaapp.com, nginx andrebbe configurato come segue:

http {
    upstream myapp1 {
        server srv1.miaapp.com;
        server srv2.miaapp.com;
        server srv3.miaapp.com;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://miaapp.com;
        }
    }
}

Con la configurazione riportata sopra, nginx provvederà a distribuire le richieste sui server da srv1 ad srv3 in modalità round-robin. In generale, quando la modalità di load balancing non è specificata, nginx utilizza round-robin per default.

Nginx può agire da distributore di carico (e quindi reverse proxy) per una serie di protocolli oltre ad HTTP. In particolare, nginx supporta HTTPS, FastCGI, uwsgi, SCGI, memcached e gRPC.

Per utilizzarlo come reverse proxy HTTPS ad esempio, è sufficiente sostituire "http" con "https" nella direttiva proxy_pass.

Modalità least-connected

Nella modalità least-connected permette di distribuire il carico in maniera più uniforme rispetto alla modalità round-robin, specialmente in quei casi in cui le richieste necessitino di più tempo per essere evase. Specificando questa modalità nginx cercherà di non sovraccaricare un server già impegnato, distribuendo il carico sui server con meno connessioni attive in quel particolare momento.

Per attivare la modalità least-connected è sufficiente aggiungere la direttiva leat_conn nel gruppo upstream. Ad esempio:

http {
    upstream myapp1 {
        least_conn;
        server srv1.miaapp.com;
        server srv2.miaapp.com;
        server srv3.miaapp.com;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://miaapp.com;
        }
    }
}

Persistenza delle sessioni

È importante sottolineare che sia nella modalità round-robin che in quella least-connected non vi è garanzia della persistenza delle sessioni. Ricordiamo infatti che HTTP è per sua natura stateless, e pertanto la gestione delle sessioni è sempre a carico del server. In uno scenario in cui è presente un load balancer, è possibile che le richieste in arrivo da uno stesso client e che logicamente appartengono ad una stessa sessione siano distribuite su application server differenti e che pertanto non saranno in grado di riconoscere gli ID o i cookie di sessione generati dagli altri.

Per ovviare a questo inconveniente bisogna configurare il load balancer in modo tale da assicurarsi che le richieste in arrivo da uno stesso client vengano sempre servite dallo stesso application server. Tale schema è implementato in nginx con la modalità ip-hash.

In ip-hash, l'indirizzo IP del client è utilizzato come chiave di hashing per la determinazione dell'application server da selezionare. Per attivare questa modalità è sufficiente specificare la direttiva ip_hash nel gruppo upstream. Ad esempio:

http {
    upstream myapp1 {
        ip_hash;
        server srv1.miaapp.com;
        server srv2.miaapp.com;
        server srv3.miaapp.com;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://miaapp.com;
        }
    }
}

Specifica dei pesi

Nginx permette di attribuire un peso numerico a ciascun application server indicato nella direttiva upstream. Server con un peso maggiore verranno selezionati più frequentemente di quelli con un peso inferiore. Per default, in assenza di una esplicita indicazione, si assume un peso pari ad 1.

Specificare dei pesi permette di distribuire il carico in maniera più consona rispetto alle reali capacitè di elaborazione degli application server. Ciò è particolarmente utile nel caso in cui gli application server girino su macchine con caratteristiche differenti.

Si supponga che l'application server srv1.miaapp.com sia in grado di gestire più richieste rispetto ai server srv2 ed srv3. In tal caso, si può assegnare ad srv1 un peso più alto per assicurarsi che esso venga selezionato più spesso dal load balancer. Ad esempio, specificando:

http {
    upstream myapp1 {
        server srv1.miaapp.com weight=3;
        server srv2.miaapp.com;
        server srv3.miaapp.com;
    }
    server {
        listen 80;
        location / {
            proxy_pass http://miaapp.com;
        }
    }
}

si assegna un peso pari a tre ad srv1 ed un peso par ad uno ad srv2 ed srv3. In questo modo, ricevute cinque richieste esse verranno distribuite come segue: tre ad srv1, una ad srv2 ed un'altra ad srv3.

Resilienza

Nginx include anche un meccanismo di monitoraggio passivo degli application server. Ciò significa che se un application server non risponde correttamente alle richieste, esso verrà marcato come non funzionante ed nginx non lo selezionerà per le richieste successive.

È possibile controllare il funzionamento di questo schema. In particolare, è possibile specificare il numero di tentativi da effettuare prima di considerare l'application server non funzionante tramite la direttiva max_fails. Per default, questo parametro è impostato ad uno, e ciò comporta che un server venga immediatamente riconosciuto come non funzionante al verificarsi del primo errore.

È inoltre possibile configurare nginx affinchè monitori lo stato dei server non funzionanti, effettuando dei controlli periodici. Il tempo che intercorre tra un controllo ed il successivo viene impostato con la direttiva fail_timeout. Per default, l'intervallo di fail_timeout à impostato a 10 secondi.

Ti consigliamo anche