j4nk3y: Node.js + socket.io, Cluster / Multithreading

Beitrag lesen

problematische Seite

Guten Morgen zusammen,

Folgendes hab ich jetzt mithilfe von diversen Modulen zusammen gestellt, was denke ich funktioniert.

Verwendet, bzw gerade installiert:
sticky-session
socket.io-redis brauch ich das??

//var cluster = require('cluster');
var http = require('http');
var threads = require('os').cpus().length;
//var redis = require('socket.io-redis');

var sticky = require('sticky-session');
var port = 1337;
var server = http.createServer()
var io = require('socket.io').listen( server );

var user = require('./functions/server/js/user');

if( !sticky.listen( server, port ) ) {
	
	console.log( '[ Node ] Server running on Port : ' + port );
	console.log( '[ Node ] Master cluster setting up ' + threads + ' threads' );
	cluster.on('online', function( thread ) {
       console.log( '[ Node ] Cluster thread ' + cluster.worker.id + ' set up' );
   });
	
   cluster.on( 'exit', function( thread, code, signal) {
       console.log( '[ Node ] Cluster thread ' + thread.id + ' died with code: ' + code + ', >and signal: ' + signal );
   });
} else {

	io.sockets.on('connection', function( socket ){

	  socket.on('getConnection', function( req ) {
			user.getConnection( socket, req, function ( res ) {
				socket.emit('setConnection', res);
			});
		});
  
  //.
  //.
  //.
});

Ist das richtig?

Also ich bekomme eine Verbindung und es werden 4 Prozesse initialisiert.
Einige kleine Tests ergeben auch das unterschiedliche Clients auf den unterschiedlichen 'workern' landen und das ein 'worker' bei einem unerwartetem 'exit' neu gestartet wird.

Wie das so ist, folgt nach einem Problem gleich das nächste. Dafür habe ich eigentlich eine Lösung, persönlich gefällt mir die aber nicht.
Ich habe ein Globales Object mit var global = require('./functions/server/js/global'); eingebunden, welches ein Abbild von (größtenteils) statischen Werten aus meiner Datenbank ist. Diese Werte nutze ich zum Beispiel in Berechnungen. Außerdem nutzen diverse Cron-jobs diese Daten um einige Werte Zeitabhängig neu zu berechnen. Diese Lösung finde ich sehr praktisch, da die Cron-jobs sowie durch einen Client getriggerte Berechnungen nicht erst die Datenbank abfragen müssen sondern direkt die Werte aus global.xyz nehmen können und die Ergebnisse in der Datenbank einfach aktualisiert werden können.
Damit nutze ich die Datenbank im Moment noch Primär als Backup, falls der Node Prozess ausfällt (und in global.js werden die Daten bei jedem Neustart des Prozesses aus der Datenbank geladen).

Lösung, alle (benötigten) Daten bei jedem Event (Client oder Cron getriggert) neu aus der Datenbank holen und dann aktualisieren. Wie gesagt, erscheint mir das nicht elegant, bietet aber den Vorteil, dass jeder 'worker' die gleichen Daten aus der Datenbank hat.

Was mich da etwas verunsichert ist, dass ich nicht weiß ob jeder 'worker' eine Referenz auf das Objekt bekommt wenn ich es zuerst im Master einbinde und dann in den einzelnen 'workern'.

Gruß
Jo