cluster sticky session

v1.18.x
barisusakli 10 years ago
parent 99e0a02b4c
commit d1fcb50c7d

@ -1,6 +1,7 @@
"use strict"; "use strict";
var nconf = require('nconf'), var nconf = require('nconf'),
net = require('net'),
fs = require('fs'), fs = require('fs'),
path = require('path'), path = require('path'),
cluster = require('cluster'), cluster = require('cluster'),
@ -13,6 +14,8 @@ var nconf = require('nconf'),
output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true }), output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true }),
silent = process.env.NODE_ENV !== 'development' ? true : false, silent = process.env.NODE_ENV !== 'development' ? true : false,
numProcs, numProcs,
handles = [],
handleIndex = 0,
Loader = { Loader = {
timesStarted: 0, timesStarted: 0,
@ -138,6 +141,15 @@ Loader.addClusterEvents = function(callback) {
case 'config:update': case 'config:update':
Loader.notifyWorkers(message); Loader.notifyWorkers(message);
break; break;
case 'sticky-session:accept':
var _handle = handles[message.handleIndex];
if (_handle) {
_handle.close();
delete handles[message.handleIndex];
}
break;
} }
} }
}); });
@ -186,6 +198,21 @@ Loader.start = function(callback) {
forkWorker(x === 0); forkWorker(x === 0);
} }
var port = nconf.get('PORT') || nconf.get('port');
var server = net.createServer(function(connection) {
// remove this once node 0.12.x ships, see https://github.com/elad/node-cluster-socket.io/issues/4
connection._handle.readStop();
handles[handleIndex] = connection._handle;
var workers = clusterWorkers();
var worker = workers[workerIndex(connection.remoteAddress, numProcs)];
worker.send({action: 'sticky-session:connection', handleIndex: handleIndex}, connection);
handleIndex ++;
}).listen(port);
if (callback) { if (callback) {
callback(); callback();
} }
@ -204,6 +231,26 @@ function forkWorker(isPrimary) {
} }
} }
function workerIndex(ip, numProcs) {
var s = '';
for (var i = 0, _len = ip.length; i < _len; i++) {
if (ip[i] !== '.') {
s += ip[i];
}
}
return Number(s) % numProcs;
}
function clusterWorkers() {
var workers = [];
for(var i in cluster.workers) {
workers.push(cluster.workers[i]);
}
return workers;
}
Loader.restart = function(callback) { Loader.restart = function(callback) {
// Slate existing workers for termination -- welcome to death row. // Slate existing workers for termination -- welcome to death row.
Loader.shutdown_queue = Loader.shutdown_queue.concat(Object.keys(cluster.workers)); Loader.shutdown_queue = Loader.shutdown_queue.concat(Object.keys(cluster.workers));

@ -124,7 +124,9 @@ if(nconf.get('ssl')) {
module.exports.listen = function(callback) { module.exports.listen = function(callback) {
var bind_address = ((nconf.get('bind_address') === "0.0.0.0" || !nconf.get('bind_address')) ? '0.0.0.0' : nconf.get('bind_address')) + ':' + port; var bind_address = ((nconf.get('bind_address') === "0.0.0.0" || !nconf.get('bind_address')) ? '0.0.0.0' : nconf.get('bind_address')) + ':' + port;
if (cluster.isWorker) {
port = 0;
}
server.listen(port, nconf.get('bind_address'), function(err) { server.listen(port, nconf.get('bind_address'), function(err) {
if (err) { if (err) {
winston.info('NodeBB was unable to listen on: ' + bind_address); winston.info('NodeBB was unable to listen on: ' + bind_address);
@ -144,4 +146,13 @@ if(nconf.get('ssl')) {
}); });
}; };
process.on('message', function(message, connection) {
if (!message || message.action !== 'sticky-session:connection') {
return;
}
server.emit('connection', connection);
process.send({action: 'sticky-session:accept', handleIndex: message.handleIndex});
});
}(WebServer)); }(WebServer));

Loading…
Cancel
Save