2011-11-16 10 views
5

Ho diverse istanze di socket.io con autenticazione in esecuzione in HAProxy e devo forzare che la richiesta di autenticazione e la connessione socket passino alla stessa istanza. Ho installato HAProxy sulla base di this answer to a SO question con alcune modifiche come in:Posso avere sessioni persistenti con HAProxy e socket.io con autenticazione?

global 
    maxconn  4096 # Total Max Connections. This is dependent on ulimit 
    nbproc  2 

defaults 
    mode  http 

frontend all 0.0.0.0:80 
    timeout client 86400000 
    default_backend www_backend 
    acl is_websocket hdr(Upgrade) -i WebSocket 
    acl is_websocket hdr_beg(Host) -i ws 

    use_backend socket_backend if is_websocket 

backend www_backend 
    balance url_param sessionId 
    option forwardfor # This sets X-Forwarded-For 
    timeout server 30000 
    timeout connect 4000 
    server server1 localhost:8081 weight 1 maxconn 1024 check 
    server server2 localhost:8082 weight 1 maxconn 1024 check 
    server server3 localhost:8083 weight 1 maxconn 1024 check 

backend socket_backend 
    balance url_param sessionId 
    option forwardfor # This sets X-Forwarded-For 
    timeout queue 5000 
    timeout server 86400000 
    timeout connect 86400000 
    server server1 localhost:8081 weight 1 maxconn 1024 check 
    server server2 localhost:8082 weight 1 maxconn 1024 check 
    server server3 localhost:8083 weight 1 maxconn 1024 check 

che ho provato url_param (dove sessionId è un parametro querystring passato sia la chiamata di autenticazione e la connessione websocket) e la fonte a titolo di saldo opzioni, ma sembra che HAProxy consenta solo queste opzioni per le connessioni HTTP e quindi le ignori per la connessione websocket effettiva. Il risultato è che a volte la richiesta di autenticazione e la connessione socket finiscono in server diversi, il che è inaccettabile per la nostra applicazione.

C'è un modo per avere questo comportamento desiderato?

+0

Hai mai capire il modo migliore per farlo? Stavo cercando di fare la stessa cosa. Grazie. –

+0

Ho finito per usare il bilanciamento dell'hash IP. Tutte le richieste dallo stesso IP vanno allo stesso server – Diego

+0

O ok, ma ciò significa che un websocket trasmesso da un utente sul server A non raggiunge nessuno degli utenti sul server B? –

risposta

0

Per il bilanciamento delle connessioni della bobina Web utilizzando roundrobin. Dal momento che il suo stickyness bidirezionale (su TCP) è mantenuto per impostazione predefinita. Per gli altri trasporti che utilizzano l'algoritmo di bilanciamento source è la soluzione migliore. (È possibile utilizzare la persistenza basato biscotto ma socket.io non invia un JSESSIONID o simile al server proxy È possibile provare sockjs se si desidera che la persistenza base biscotto..)

Esempio:

#do the same for other transports. [Note in 0.6.x resource was mounted at path: /socket.io/[transport] 
acl is_JSONPolling path_beg /socket.io/1/jsonp-polling 
use_backend non_websocket if is_JSONPolling 


backend non_websocket 
    balance source 
    #rest same as the one for websocket backend 
+0

Il problema è che la richiesta di autenticazione e la connessione web socket possono finire in diversi server. C'è un modo per farli andare sempre allo stesso server? Sapresti se un altro sistema di bilanciamento del carico lo fornisce? – Diego

+0

Non importa quale server viene colpito, a condizione che l'archivio di autenticazione sia separato dall'app. Spero che tu non stia utilizzando la memoria come negozio per le sessioni di autenticazione. Usa qualcosa come Redis per memorizzare la chiave di autenticazione. Dai un'occhiata alla mia risposta qui per la gestione di auth: http://stackoverflow.com/questions/4753957/socket-io-authentication/4754806#4754806 –

2

Per bilanciare la connessione TCP, è possibile avere successo con una tabella di stickiness utilizzando i comandi stick_match o stick on e impostando esplicitamente la modalità tcp.

Ecco un esempio:

# forward SMTP users to the same server they just used for POP in the 
# last 30 minutes 
backend pop 
    mode tcp 
    balance roundrobin 
    stick store-request src 
    stick-table type ip size 200k expire 30m 
    server s1 192.168.1.1:110 
    server s2 192.168.1.1:110 

backend smtp 
    mode tcp 
    balance roundrobin 
    stick match src table pop 
    server s1 192.168.1.1:25 
    server s2 192.168.1.1:25 

documentazione completa disponibile here.

9

Io uso bilanciamento basato biscotto in questo modo:

backend socketio 
    mode http 
    cookie SIO insert 
    server sock1 127.0.0.1:8001 cookie 001 
    server sock2 127.0.0.1:8002 cookie 002 
+0

Per il metodo cookie, c'è un modo per impostare il periodo di timeout del cookie? – Alessandro

0

Stai usando HTTP in modo da inserire un cookie per la persistenza - che è sicuramente la strada migliore. Questo lo attaccherà al primo server in cui sono andati, a meno che non sia giù.

È anche possibile configurare se debba rispedire se è giù ecc