Home > Article > Web Front-end > Use cluster to expand your Node server into a multi-threaded server_node.js
Friends who use nodejs all know that node is single-threaded, which means that it runs on an 8-core CPU and can only use the computing power of one core.
Single threading has always been a criticism of node, 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 into a multi-threaded server.
What is Cluster
Cluster is a multi-threading library provided by node. Users can use it to create multiple threads. The threads share a listening port. When there is an external request for this port, the cluster will forward the request to a random thread. Because each node thread will occupy dozens of megabytes of memory, you cannot create a thread for each request like PHP does. Generally speaking, the number of threads created will not exceed the number of cores of the CPU at most.
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 worldn");
}).listen(8000);
}
As shown in the above code, cluster.isMaster will be set to true when the program is running. After calling cluster.fork(), the program will create a thread and run it again. At this time, cluster.isMaster will be set to false. . We mainly use this variable to determine whether the current thread is a child thread.
You can also notice 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 exchanges can only be processed in the main thread through worker.send and worker.on('message', handler). Here is an example of a broadcast system.
if (cluster.isMaster) {
var workers=[];
//Create new worker
function newWorker(){
var worker=cluster.fork();
//Listen to information, if the type is broadcast, it is determined to be broadcast
worker.on('message', function(msg) {
If(msg.type=='broadcast'){
var event=msg.event;
//Send this broadcast to all workers
workers.forEach(function(worker){
worker.send(event);
})
}
});
Return worker;
}
for (var i = 0; i < numCPUs; i ) {
Workers.push(newWorker());
}
cluster.on('online',function(worker){
console.log('worker %d is online',worker.id);
})
} else {
var worker=cluster.worker;
//Broadcast is to send a message of type broadcast, and event is the broadcast content
worker.broadcast=function(event){
worker.send({
Type:'broadcast',
event:event
});
}
//It seems that the returned information cannot be monitored using worker.on here
process.on('message',function(event){
console.log('worker: ' worker.id ' recived event from ' event.workerId);
})
//Send broadcast
worker.broadcast({
Message:'online',
workerId:worker.id
})
}
Issues that need attention
As mentioned above, data cannot be shared between threads, and all data exchange can only be exchanged through communication between threads. And the data exchanged is all serializable, so things like functions, file descriptors and HttpResponse cannot be passed.
If you use cluster, you need to consider the issue of data exchange during program design. My own approach is to store data like sessions in redis, and each thread does a good job of accessing it. None of the data is placed in node memory.
Last point, cluster is currently officially marked as Experimental by Node, and the API may change in the future.