This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
node.js on multi-core machines
Since node.js makes use of single thread model, how can node.js leverage multiple cores?
Without using multiple cores, I think the usage of CPU is not enough, am I right?
you can use the core cluster module
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}
Related
I am using clusters in my node.js server and I have a middlewere function that is saving weekly some data to db. The issue is that I am using three workers and this function is executed three times and it saves 3 documents in the DB. How can I avoid this and still use clusters?
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// execute the one time function
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
you can do that by executing it inside the if statement or where your master code executes. this way you can just run it once.
https://nodejs.org/api/cluster.html
Your nodejs program can tell whether it's the master with cluster.isMaster().
Your master can update your weekly data. Or, if all your workers have to generate their own data, they can do that, then the master can read it all and create just one document.
Nodejs is asynchronous. But single threaded. When a synchronous workload is executed, the event loop is blocked.
Can we make node multi threaded to increase performance?
You can look into cluster mode in recent versions of Node.js.
Quoting the example from the above page for reference:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
This code starts a number of workers, and you see a clear separation between master and worker code.
These processes can communicate by sending messages.
i was reading nodejs cluster to run multiple instances of node appication
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
}
else {
http.createServer((req, res) => {
res.writeHead(200);
res.end('hello world\n');
}).listen(8000);
console.log(`Worker ${process.pid} started`);
}
is using this approach good in a production environment.
where the number of requests is more
You can rather use pm2/strongloop for managing this.Because all these modules are production ready and really easy to manage.
I personally feel pm2 is awesome to manage node processes.
Use following link to know more about pm2
http://pm2.keymetrics.io/
Yes you can use cluster for as long as you are calculating your cpu length
const numCPUs = require('os').cpus().length;
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
The cluster won't create processes more than that of the cpu length
But if clusters are not manage properly it will slow down the entire application process
I understand that I can use Nodes cluster module in order to create several workers all serving the same socket connection (example from docs):
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}
However, what if I instead of serving the same connection want each worker to run their own server, each listening on a separate port?
You can pass environment variables to each child, allowing the master process to assign them ports:
var cluster = require('cluster');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
var pidToPort = {};
var worker, port;
for (var i = 0; i < numCPUs; i++) {
port = 8000 + i;
worker = cluster.fork({port: port});
pidToPort[worker.process.pid] = port;
}
console.log(pidToPort);
cluster.on('exit', function(worker, code, signal) {
// Use `worker.process.pid` and `pidToPort` to spin up a new worker with
// the port that's now missing. If you do so, don't forget to delete the
// old `pidToPort` mapping and add the new one.
console.log('worker ' + worker.process.pid + ' died');
});
} else {
// Start listening on `process.env.port` - but first, remember that it has
// been cast to a string, so you'll need to parse it.
console.log(process.env.port);
}
i am trying to understand the following piece of code that is use to create miltiple servers to make use of a multi core cpu.
var cluster = require("cluster");
var http = require("http");
var numCPUs = require("os").cpus().length;
var port = parseInt(process.argv[2]);
if (cluster.isMaster) {
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on("exit", function(worker, code, signal) {
cluster.fork();
});
} else {
http.createServer(function(request, response) {
console.log("Request for: " + request.url);
response.writeHead(200);
response.end("hello world\n");
}).listen(port);
}
my question is, given every created server listens on same port, what guarantees that a request won't be served by more than one server?
In node v0.10, the OS kernel always chooses which child gets the request. In node v0.11+ and io.js v1.0.0+, manual round-robin scheduling is used (except on Windows for now). This default behavior is configurable by setting an environment variable though.