2013-07-25 11 views
5

ich bin node.js zum ersten Mal und in der Hoffnung für eine Beratung mit:node.js + socket.io + redis Architektur - horizontale Servercaling-Socket-Verbindungen?

i installiert die folgenden Programme auf meinem Server:

  • node.js v0.11.3-pre
  • express v3.3.4
  • socket.io v0.9.14
  • Connect-redis v1.4.5
  • Redis Server v = 2.6.14
  • redis -cli 2.6.14

Zu allererst i eine ausdrückliche App erstellt:

express testApplication 

in der geschaffenen "package.json" definiert i alle notwendigen Depencies.

Von Anfang an definiert i einen Cluster für die vertikale Skalierung (Multi-Prozesse) in einer Datei "cluster.js" genannt:

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(); 
}); 

In meiner "app.js" Datei definiert i REDIS für Sockel. io Speicherung:

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

So weit, so gut, das alles funktioniert ziemlich gut.

Wenn ein Client eine Verbindung zum Server socket.io herstellt, verarbeitet der Cluster die Verbindungen mit verschiedenen Arbeitern.

Meine Absicht ist, dass ein Client eine Nachricht an einen bestimmten anderen Client senden kann, damit der socket.io Server den Socket vom Empfänger finden muss, um die Nachricht nur an diesen Benutzer zu senden. Die Lösung für mich ist, dass ich alle erstellten Socket-IDs für jeden Benutzer in einem Array ablege und beim Senden einer Nachricht die relevanten Socket-IDs im Array auswähle, die Sockets per ID abrufe und die Nachricht an den Socket sende (s).

Dies funktioniert sehr gut für eine socket.io-Anwendung, die nur auf einem Server ausgeführt wird. Jetzt möchte ich einen anderen Server mit den gleichen Programmen, Modulen und Paketen konfigurieren. Der Lastenausgleich wird wahrscheinlich von HAProxy gehandhabt. So werden die Socket.io-Verbindungen (Sockets) unter Server A und Server B gespeichert und verwaltet.

Beispielszenario:

Benutzer A Verbindung zu Server A und Benutzer B Verbindung zu Server B. Das heißt, dass Benutzer A einen Socket auf Server A und Benutzer B auf Server B hat.

Wie ist es möglich, dass die Anwendung weiß, dass sie nach dem Socket von Benutzer B auf Server B suchen muss, um den Botschaft? Auf Server A wird der Socket nicht gefunden, da er auf Server B erstellt wurde.

Vielen Dank!

Antwort

5

Wenn Sie horizontal skalieren, müssen Sie einen Datenspeicher zwischen Ihren Servern freigeben. Praktischerweise haben Sie bereits einen idealen, nämlich Redis. Anstatt Ihre Socket-Zuordnung in einem Array zu halten, müssen Sie sie in Redis schieben und von dort aus nachschlagen.

Dann können Sie entscheiden, ob die Server Nachrichten untereinander senden sollen oder, noch besser, die Nachrichten auch über Redis senden. Jeder Server würde also seine Warteschlange auf Redis überprüfen, um zu sehen, welche Nachrichten an welche Sockets gesendet werden sollen. Wenn ein Server eine Nachricht erhält, wird sie in Redis übertragen, die an den Server adressiert ist, der sie übermitteln soll. Wenn die Reihenfolge der Nachrichten für Sie wichtig ist, würde ich empfehlen, https://github.com/learnboost/kue als Ebene über Redis zu betrachten.

+0

@elchueko Können Sie ein Beispiel veröffentlichen, wie Sie es mit redis gelöst haben? – patrick

Verwandte Themen