To implement sticky sessions in a Node.js app running in cluster mode, ensuring the same client always hits the same server, you can follow these steps.
Steps to Implement Sticky Sessions:
Cluster Setup:
Use the cluster module in Node.js to create multiple worker processes. Each worker can handle incoming requests independently. In a clustered environment, the operating system balances the load between the workers.
Example:
const cluster = require('cluster');
const http = require('http');
const os = require('os');
const app = require('express')();
if (cluster.isMaster) {
// Fork workers for each CPU core
const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`Worker ${worker.process.pid} died`);
});
} else {
// Worker processes can share the same server
http.createServer(app).listen(3000, () => {
console.log(`Worker ${process.pid} started`);
});
}
Sticky Sessions with Sticky-Session Library: To ensure the same client hits the same worker, you'll need sticky sessions. The sticky-session library helps achieve this by ensuring that requests from the same client go to the same worker process.
Install the sticky-session library:
npm install sticky-session
Then, modify the above code to use sticky-session:
const sticky = require('sticky-session');
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
if (sticky.listen(app, 3000)) {
console.log('Server started on port 3000');
}
Configure Load Balancer (Optional for Distributed Clusters): In a cloud or distributed environment, you may need a load balancer to route traffic. To maintain sticky sessions across multiple machines, configure the load balancer (e.g., Nginx, HAProxy) to support sticky sessions. This will route requests from the same client to the same Node.js worker process.
Session Management: Ensure that session data is shared across workers (since each worker is separate). You can use shared session storage like Redis, which ensures that when a client reconnects, their session is available to the worker handling the request.
Example using Redis session store:
npm install express-session connect-redis redis
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const client = redis.createClient();
app.use(session({
store: new RedisStore({ client: client }),
secret: 'mySecret',
resave: false,
saveUninitialized: true
}));