Created
September 7, 2018 18:10
-
-
Save mStirner/c835bea5b0f8a518c4a8f6348d898ada to your computer and use it in GitHub Desktop.
nodejs cluster without redis, support sticky balancing / websockets
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const cluster = require("cluster"); | |
const http = require("http"); | |
const os = require("os"); | |
const net = require("net"); | |
const ip = require('ip'); | |
// create seed | |
const seed = (Math.random() * 0xffffffff) | 0; | |
/** | |
* Hash IP | |
* @type Number|seed | |
*/ | |
function hashHelper(ip) { | |
var hash = seed; | |
for (var i = 0; i < ip.length; i++) { | |
var num = ip[i]; | |
hash += num; | |
hash %= 2147483648; | |
hash += (hash << 10); | |
hash %= 2147483648; | |
hash ^= hash >> 6; | |
} | |
hash += hash << 3; | |
hash %= 2147483648; | |
hash ^= hash >> 11; | |
hash += hash << 15; | |
hash %= 2147483648; | |
return hash >>> 0; | |
} | |
// create standard http server | |
// can be in the cluster.isMaster else statemant (is slave/!isMaster) | |
var server = http.createServer(function (req, res) { | |
res.end("Hello from, pid: " + process.pid); | |
}); | |
if (cluster.isMaster) { | |
// workers | |
let workers = []; | |
let tcp = net.Server({ | |
pauseOnConnect: true | |
}, function balance(socket) { | |
var addr = ip.toBuffer(socket.remoteAddress || '127.0.0.1'); | |
var hash = hashHelper(addr); | |
// feedback | |
console.log('balancing connection %j', addr); | |
// send request to worker | |
workers[hash % workers.length].send('sticky:balance', socket); | |
}); | |
// liste for listening event | |
tcp.once('listening', function () { | |
let addr = this.address(); | |
console.log('Cluster (master) listening on %s:%d', addr.address, addr.port); | |
for (var i = 0; i < os.cpus().length; i++) { | |
let worker = cluster.fork(); | |
workers.push(worker); | |
// feedback | |
console.log('worker=%d spawn', worker.process.pid); | |
} | |
}); | |
// start tcp server | |
tcp.listen(3000, "0.0.0.0"); | |
} else { | |
process.on('message', function (msg, socket) { | |
if (msg !== 'sticky:balance' || !socket) { | |
return; | |
} | |
server._connections++; | |
socket.server = server; | |
server.emit('connection', socket); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Based on the sticky-session module.
Support WebSockets, socket.io, Sessions & Cookies
Why ?
Because reasons....