2013-07-25 11 views
5

sto usando node.js per la prima volta e sperando in un consiglio:node.js + socket.io + architettura redis - connessioni socket servercaling orizzontali?

ho installato i seguenti programmi sul mio server:

  • node.js v0.11.3-pre
  • espresso v3.3.4
  • socket.io v0.9.14
  • connect-Redis v1.4.5
  • server di Redis v = 2.6.14
  • Redis -cli 2.6.14

Prima di tutto, ho creato un app espresso:

express testApplication 

Nella "package.json" creato i definito tutti depencies necessario.

Fin dall'inizio ho definito un cluster per il ridimensionamento verticale (multi-processi) in un file chiamato "cluster.js":

var cluster = require('cluster'); 

if(cluster.isMaster) { 
     var noOfWorkers = process.env.NODE_WORKERS || require('os').cpus().length; 

     console.log("Workers found: " + noOfWorkers); 

     for (var i = 0; i < noOfWorkers; i += 1) { 
       cluster.fork(); 
     } 
} else { 
     require('./app.js'); 
} 

cluster.on('exit', function(worker, code, signal) { 
     var exitCode = worker.process.exitCode; 

     console.log('worker' + worker.process.pid + ' died (' + exitCode + '). restarting...'); 

     if(typeof cluster.workers[worker.id] != "undefined") 
       cluster.workers[worker.id].delete(); 

     cluster.fork(); 
}); 

Nel mio file "app.js" ho definito REDIS per il socket. io memorizzazione:

io.set('store', new RedisStore({ 
      redisPub: pub, 
      redisSub: sub, 
      redisClient: client 
      })); 

Fin qui, tutto bene, tutto questo funziona abbastanza piacevole.

Quando un client si connette al server socket.io, il cluster gestisce le connessioni con diversi worker.

La mia intenzione è che un client possa inviare un messaggio a un altro client specifico, quindi il server socket.io deve trovare il socket dal ricevente per inviare il messaggio solo a questo utente. La soluzione per me è che io memorizzo tutti gli ID socket creati per ogni utente in un array e quando invio un messaggio, seleziono i relativi ID socket nell'array, ottengo i socket tramite id, e inviamo il messaggio al socket).

Questo funziona molto bene per un'applicazione socket.io, che è in esecuzione solo su un server. Ora, voglio configurare un altro server con gli stessi programmi, moduli e pacchetti. Il bilanciamento del carico verrà probabilmente gestito da HAProxy. Le connessioni socket.io (socket) verranno quindi archiviate e gestite sul server A e Server B.

Scenario di esempio:

utente A si connette al server A e utente B connette a Server B. Ciò significa che l'Utente A ha un socket sul Server A e l'Utente B sul Server B.

Come è possibile che l'applicazione sappia che deve cercare il socket dell'Utente B sul Server B per inviare il Messaggio? Sul server A non troverà il socket, perché è stato creato sul server B.

Grazie mille!

risposta

5

Quando si esegue il ridimensionamento orizzontale, è necessario condividere un archivio dati tra i server. Convenientemente, ne hai già uno ideale, ovvero Redis. Invece di mantenere il mapping del socket in un array, è necessario inserirlo in Redis e fare le ricerche da lì.

Quindi, è possibile decidere se i server devono inviare messaggi tra loro o, in modo più scalabile, inviare anche i messaggi tramite Redis. Quindi, ogni server guarderebbe la coda su Redis per vedere quali messaggi dovrebbe inviare a quali socket. Quando un server riceve un messaggio, lo invia in Redis indirizzato al server che dovrebbe consegnarlo. Se l'ordine dei messaggi è importante per te, ti consiglio di guardare a https://github.com/learnboost/kue come strato in cima a Redis.

+0

@elchueko Puoi pubblicare un esempio come hai risolto con redis? – patrick

Problemi correlati