Implementing an HTTP Cluster

The best way to illustrate the value of the cluster module is to show a basic implementation of Node.js HTTP servers. Listing 9.7 implements a basic cluster of HTTP servers. Lines 4–13 register listeners for the fork, listening, and exit events on cluster workers. Then the code in line 14 calls setupMaster() and specifies the worker executable cluster_worker.js. Next, lines 15–19 create the workers by calling cluster.fork(). Finally, on lines 20–24 the code iterates through the workers and registers an on('message') event handler for each one.

The code in Listing 9.8 implements the worker HTTP servers. Notice that the HTTP server sends back a response to the client and then also sends a message to the cluster master on line 7.

The code in Listing 9.9 implements a simple HTTP client that sends a series of requests to test the servers created in Listing 9.8. Figure 9.6 shows the output of the servers, and Figure 9.7 shows the output of the clients. Notice that the output in Figure 9.7 shows that the requests are being handled by different processes on the server.


Note

To execute the files shown in Listings 9.7, 9.8 and 9.9, first execute the cluster_server.js file as a node application and then execute the cluster_client.js file as a node application. The cluster_worker.js file is executed in the background by the cluster_server.js file.


Listing 9.7 cluster_server.js: A master process creating up to four worker processes


01 var cluster = require('cluster'),
02 var http = require('http'),
03 if (cluster.isMaster) {
04   cluster.on('fork', function(worker) {
05     console.log("Worker " + worker.id + " created");
06   });
07   cluster.on('listening', function(worker, address) {
08     console.log("Worker " + worker.id +" is listening on " +
09                 address.address + ":" + address.port);
10   });
11   cluster.on('exit', function(worker, code, signal) {
12     console.log("Worker " + worker.id +" Exited");
13   });
14   cluster.setupMaster({exec:'cluster_worker.js'});
15   var numCPUs = require('os').cpus().length;
16   for (var i = 0; i < numCPUs; i++) {
17     if (i>=4) break;
18     cluster.fork();
19   }
20   Object.keys(cluster.workers).forEach(function(id) {
21     cluster.workers[id].on('message', function(message){
22       console.log(message);
23     });
24   });
25 }


Listing 9.8 cluster_worker.js: A worker process implementing an HTTP server


01 var cluster = require('cluster'),
02 var http = require('http'),
03 if (cluster.isWorker) {
04   http.Server(function(req, res) {
05     res.writeHead(200);
06     res.end("Process " + process.pid + " says hello");
07     process.send("Process " + process.pid + " handled request");
08   }).listen(8080, function(){
09     console.log("Child Server Running on Process: " + process.pid);
10   });
11 };


Listing 9.9 cluster_client.js: An HTTP client sending a series of requests to test the server


01 var http = require('http'),
02 var options = { port: '8080'};
03 function sendRequest(){
04   http.request(options, function(response){
05     var serverData = '';
06     response.on('data', function (chunk) {
07       serverData += chunk;
08     });
09     response.on('end', function () {
10       console.log(serverData);
11     });
12   }).end();
13 }
14 for (var i=0; i<5; i++){
15   console.log("Sending Request");
16   sendRequest();
17 }


Image

Figure 9.6 Output of the cluster server, showing creation and interaction with workers.

Image

Figure 9.7 Output of the cluster client, showing results including process IDs of worker processes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.69.50