Friends who use nodejs all know that node is single-threaded, which means that when running on an 8-core CPU, you can only use one core's computing power.
Single threading has always been a criticism of nodes, but with the introduction of cluster in version 0.6, this situation has changed. Developers can rely on cluster to easily expand their Node server to multi-threaded server.
What is Cluster
cluster is a multi-threaded library provided by node. Users can use it to create multiple threads. The threads share a listening port. When there is an external request to this port, cluster will forward the request to a random thread. Because each node thread will occupy tens of megabytes of memory, it is impossible to create a thread for each request like PHP. Generally speaking, the number of threads created will not exceed the number of CPU cores at most.
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if () {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
();
}
('exit', function(worker, code, signal) {
('worker ' + + ' died');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
(function(req, res) {
(200);
("hello world\n");
}).listen(8000);
}
As shown in the above code, the program will be set to true when running. After calling(), the program will create a thread and rerun it, which will be set to false. We mainly use this variable to determine whether the current thread belongs to a child thread.
It can also be noted that after each child thread is created, it will listen to port 8000 without causing conflicts. This is the function of cluster shared ports.
Communication between threads
When threads are created, they do not share memory or data with each other. All data exchange can only be processed in the main thread through the sum ('message', handler). The following lists an example of a broadcast system.
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if () {
var workers=[];
//Create a new worker
function newWorker(){
var worker=();
//Supervising information, if the type is broadcast, it is determined to be broadcast
('message', function(msg) {
if(=='broadcast'){
var event=;
//Send this broadcast to all workers
(function(worker){
(event);
})
}
});
return worker;
}
for (var i = 0; i < numCPUs; i++) {
(newWorker());
}
('online',function(worker){
('worker %d is online',);
})
} else {
var worker=;
//Broadcast is to send a message with type broadcast, event is broadcast content
=function(event){
({
type:'broadcast',
event:event
});
}
//This is where you cannot monitor the returned information
('message',function(event){
('worker: '++' recived event from '+);
})
//Send broadcast
({
message:'online',
workerId:
})
}
Issues to be aware of
It is also mentioned above that data cannot be shared between threads, and all data exchanges can only be exchanged through communication between threads. Moreover, the exchanged data is serializable, so things like functions, file descriptors, and HttpResponse cannot be passed.
If you use cluster, you need to consider the data exchange problem when designing the program. My own approach is to store all the data similar to the session in Redis, and each thread does the storage and withdrawal work, and all the data is not placed in node memory.
Last point, cluster is currently officially marked as Experimental by Node, and the API may change in the future.