码迷,mamicode.com
首页 > Web开发 > 详细

[Node.js] Load balancing a Http server

时间:2019-03-08 23:35:24      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:图片   div   sig   second   nbsp   some   col   int   pid   

Let‘s see how to do load balancing in Node.js.

 

Before we start with the solution, you can do a test to see the ability concurrent requests your current machine can handle.

This is our server.js:

const http = require(http);
const pid = process.pid;
// listen the mssage event on the global
// then do the computation
process.on(message, (msg) => {
    const sum = longComputation();
    process.send(sum);
})

http.createServer((req, res) => {
    for (let i = 0; i<1e7; i++); // simulate CPU work
    res.end(`Handled by process ${pid}`)
}).listen(8000, () => {
    console.log(`Started process ${pid}`);
})

 

Test 200 concurrent requests in 10 seconds.

ab -c200 -t10 http:localhost:8000/

 

For one single node server can handle 51 requsts / second:

技术图片

 

Create cluster.js:

// Cluster.js
const cluster = require(cluster);
const os = require(os);

// For runing for the first time,
// Master worker will get started
// Then we can fork our new workers
if (cluster.isMaster) {
    const cpus = os.cpus().length;

    console.log(`Forking for ${cpus} CPUs`);
    for (let i = 0; i < cpus; i++) {
        cluster.fork();
    }
} else {
    require(./server); 
}

For the first time Master worker is running, we just need to create as many workers as our cpus allows. Then next run, we just require our server.js; that‘s it! simple enough!

 

Running:

node cluster.js

When you refresh the page, you should be able to see, we are assigned to different worker.

 

Now, if we do the ab testing again:

ab -c200 -t10 http:localhost:8000/

 

The result is 181 requests/second!

技术图片

 


 

 

Sometimes it would be ncessary to communcation between master worker and cluster wokers.

Cluster.js:

We can send information from master worker to each cluster worker:

const cluster = require(cluster);
const os = require(os);

// For runing for the first time,
// Master worker will get started
// Then we can fork our new workers
if (cluster.isMaster) {
    const cpus = os.cpus().length;

    console.log(`Forking for ${cpus} CPUs`);
    for (let i = 0; i < cpus; i++) {
        cluster.fork();
    }

    console.dir(cluster.workers, {depth: 0});
    Object.values(cluster.workers).forEach(worker => {
        worker.send(`Hello Worker ${worker.id}`);
    })
} else {
    require(./server); 
}

 

In the server.js, we can listen to the events:

const http = require(http);
const pid = process.pid;
// listen the mssage event on the global
// then do the computation
process.on(message, (msg) => {
    const sum = longComputation();
    process.send(sum);
})

http.createServer((req, res) => {
    for (let i = 0; i<1e7; i++); // simulate CPU work
    res.end(`Handled by process ${pid}`)
}).listen(8000, () => {
    console.log(`Started process ${pid}`);
})

process.on(‘message‘, msg => {
    console.log(`Message from master: ${msg}`)
})

 


 

 

A one patical example would be count users with DB opreations;

// CLuster.js

const cluster = require(cluster);
const os = require(os);
/**
 * Mock DB Call
 */
const numberOfUsersDB = function() {
    this.count = this.count || 6;
    this.count = this.count * this.count;
    return this.count;
}

// For runing for the first time,
// Master worker will get started
// Then we can fork our new workers
if (cluster.isMaster) {
    const cpus = os.cpus().length;

    console.log(`Forking for ${cpus} CPUs`);
    for (let i = 0; i < cpus; i++) {
        cluster.fork();
    }

    const updateWorkers = () => {
        const usersCount = numberOfUsersDB();
        Object.values(cluster.workers).forEach(worker => {
            worker.send({usersCount});
        });
    }

    updateWorkers();
    setInterval(updateWorkers, 10000);
} else {
    require(./server);
}

Here, we let master worker calculate the result, and every 10 seconds we send out the result to all cluster workers.

 

Then in the server.js, we just need to listen the request:

let usersCount;
http.createServer((req, res) => {
    for (let i = 0; i<1e7; i++); // simulate CPU work
    res.write(`Users ${usersCount}`);
    res.end(`Handled by process ${pid}`)
}).listen(8000, () => {
    console.log(`Started process ${pid}`);
})

process.on(message, msg => {
    usersCount = msg.usersCount;
})

 

[Node.js] Load balancing a Http server

标签:图片   div   sig   second   nbsp   some   col   int   pid   

原文地址:https://www.cnblogs.com/Answer1215/p/10498717.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!