Nodejs added a cluster module after v0.6.x to implement multi-process. It uses the child_process module to create and manage processes and increase program performance on multi-core CPU machines. This article describes how to create multiple threads using the cluster module. All friends who use nodejs know that node is single-threaded. That is to say, it runs on an 8-core CPU and can only use the computing power of one core.
A single thread has always been a criticism of node, but with the introduction of cluster in version 0.6, this situation has changed, developers can easily extend their Node servers to multi-threaded servers by relying on the cluster.
What is Cluster?
Cluster is a multi-threaded library provided by node. You can use it to create multiple threads and share a listening port between threads. When an external request is sent to this port, the cluster forwards the request to a random thread. Because each node thread occupies dozens of megabytes of memory, you cannot create a thread for each request like php. Generally, the maximum number of threads created will not exceed the number of cpu cores.
The Code is as follows:
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 ('eg', 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 );
}
As shown in the code above, cluster is running. isMaster is set to true when cluster. after fork (), the program will create a thread and run it again. isMaster is set to false. We mainly use this variable to determine whether the current thread is a subthread.
You can also note that after each sub-thread is created, it listens to port 8000 without causing a conflict. This is the function of the cluster shared port.
Communication between threads
After a thread is created, it does not share memory or data with each other. All data exchange can only be processed in the main thread through worker. send and worker. on ('message', handler). The following lists an instance of a broadcast system.
The Code is as follows:
Var cluster = require ('cluster ');
Var http = require ('http ');
Var numCPUs = require ('OS'). cpus (). length;
If (cluster. isMaster ){
Var workers = [];
// Create a worker
Function newWorker (){
Var worker = cluster. fork ();
// Listener 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 refers to sending a message with the broadcast type, and event refers to the broadcast content.
Worker. broadcast = function (event ){
Worker. send ({
Type: 'broadcast ',
Event: event
});
}
// Worker. on seems to be unable to monitor the returned information.
Process. on ('message', function (event ){
Console. log ('worker: '+ worker. id + 'recived event from' + event. workerId );
})
// Send Broadcast
Worker. broadcast ({
Message: 'online ',
WorkerId: worker. id
})
}
Notes
As mentioned above, data cannot be shared between threads, and all data exchanges can only be exchanged through communication between threads. In addition, the exchanged data is serializable. Therefore, functions, file descriptors, and HttpResponse cannot be transmitted.
If cluster is used, data exchange needs to be considered during programming. My own practice is to store all the data similar to session in redis, every thread makes access, and all data is not stored in the node memory.
Finally, the cluster is officially marked as Experimental by Node, and the api may change in the future.