Nginx e CentOS: creare un load balancer per i Websocket di nodejs

In questo post ho riportato il codice bash (di mia stesura) necessario per eseguire l’applicativo nodejs come demone (senza avvelersi quindi di tool esterni quali nohup o screen). In soldoni, esso non fa altro che tirare su (o stoppare/riavviare) 8 istanze di nodejs (ciascuna delle quali è in ascolto su una porta TCP dedicata, dalla 9001 alla 9008), il cui compito è quello di gestire le connessioni Websocket in ingresso (tramite la libreria socket.io ed il metodo HTTP Upgrade).

Nel caso in cui vi fosse la necessità di distribuire le istanze di nodejs su più macchine (per questioni di ridondanza e di suddivisione del carico), è indispensabile avvalersi di un bilanciatore in grado di gestire la suddetta tipologia di traffico (Websocket).

A tal proposito, se si vuole optare per una soluzione “software”, non si hanno tantissime alternative e le più gettonate sono sicuramente HAProxy e Nginx. Il primo è un bilanciatore a tutti gli effetti, mentre il secondo è un server Web (a detta di molti più performante e malleabile di Apache), che però può essere configurato a mo’ di load balancer.

La scelta è ricaduta proprio su Nginx perchè si è rivelato essere molto più stabile rispetto ad HAProxy (quest’ultimo crashava inesorabilmente se le richieste di connessione provenivano dal browser Safari).

Di seguito riporto la configurazione di Nignx, supponendo che vi siano 3 frontend da bilanciare, ciascuno dei quali dotato di 8 istanze nodejs:

upstream node_app {
    ip_hash;
    server node1.domain.com:9001;
    server node1.domain.com:9002;
    server node1.domain.com:9003;
    server node1.domain.com:9004;
    server node1.domain.com:9005;
    server node1.domain.com:9006;
    server node1.domain.com:9007;
    server node1.domain.com:9008;
    server node2.domain.com:9001;
    server node2.domain.com:9002;
    server node2.domain.com:9003;
    server node2.domain.com:9004;
    server node2.domain.com:9005;
    server node2.domain.com:9006;
    server node2.domain.com:9007;
    server node2.domain.com:9008;
    server node3.domain.com:9001;
    server node3.domain.com:9002;
    server node3.domain.com:9003;
    server node3.domain.com:9004;
    server node3.domain.com:9005;
    server node3.domain.com:9006;
    server node3.domain.com:9007;
    server node3.domain.com:9008;
}

server {
    server_name lblive.domain.com;
    listen 80;
    location / {
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://node_app;
    }
}

La configurazione è abbastanza intuitiva: nella prima parte viene definito l’elenco dei frontend e la politica di bilanciamento (stickyip_hash), mentre nella seconda parte vengono definite le regole per la gestione del traffico (soprattutto per ciò che concerne gli header HTTP).

A configurazione completata avviamo Nginx:

[root@loadbalancer ~]# service nginx start

e facciamo in modo che venga eseguito automaticemente dopo ogni riavvio:

[root@loadbalancer ~]# chkconfig nginx on

E’ tutto. Alla prossima.

Nginx e CentOS: creare un load balancer per i Websocket di nodejsultima modifica: 2015-08-17T15:34:07+02:00da nazarenolatella
Reposta per primo quest’articolo