Javascript NodeJS集群,真的需要吗?

Javascript NodeJS集群,真的需要吗?,javascript,node.js,express,server,node-cluster,Javascript,Node.js,Express,Server,Node Cluster,我决定研究使用NodeJS服务器处理大量流量的最佳方法,我在2台具有1GB RAM/2 CPU的digital ocean服务器上做了一个小测试 没有群集服务器代码: // Include Express var express = require('express'); // Create a new Express application var app = express(); // Add a basic route – index page app.get('/', functio

我决定研究使用NodeJS服务器处理大量流量的最佳方法,我在2台具有1GB RAM/2 CPU的digital ocean服务器上做了一个小测试 没有群集服务器代码:

// Include Express
var express = require('express');

// Create a new Express application
var app = express();

// Add a basic route – index page
app.get('/', function (req, res) {
    res.redirect('http://www.google.co.il');
});

// Bind to a port
app.listen(3000);
console.log('Application running');
    // Include the cluster module
var cluster = require('cluster');
// Code to run if we're in the master process
if (cluster.isMaster) {
    // Count the machine's CPUs
    var cpuCount = require('os').cpus().length;

    // Create a worker for each CPU
    for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
    }
// Code to run if we're in a worker process
} else {
    // Include Express
    var express = require('express');

    // Create a new Express application
    var app = express();

    // Add a basic route – index page
    app.get('/', function (req, res) {
        res.redirect('http://www.walla.co.il');
    });

    // Bind to a port
    app.listen(3001);
    console.log('Application running #' + cluster.worker.id);
}
群集服务器代码:

// Include Express
var express = require('express');

// Create a new Express application
var app = express();

// Add a basic route – index page
app.get('/', function (req, res) {
    res.redirect('http://www.google.co.il');
});

// Bind to a port
app.listen(3000);
console.log('Application running');
    // Include the cluster module
var cluster = require('cluster');
// Code to run if we're in the master process
if (cluster.isMaster) {
    // Count the machine's CPUs
    var cpuCount = require('os').cpus().length;

    // Create a worker for each CPU
    for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
    }
// Code to run if we're in a worker process
} else {
    // Include Express
    var express = require('express');

    // Create a new Express application
    var app = express();

    // Add a basic route – index page
    app.get('/', function (req, res) {
        res.redirect('http://www.walla.co.il');
    });

    // Bind to a port
    app.listen(3001);
    console.log('Application running #' + cluster.worker.id);
}
//包括集群模块
var cluster=require('cluster');
//在主进程中运行的代码
if(cluster.isMaster){
//计算机器的CPU数
var cpuCount=require('os').cpus().length;
//为每个CPU创建一个工作进程
对于(变量i=0;i
我向这些服务器发送了压力测试请求,我认为集群服务器将处理更多的请求,但没有发生,两台服务器在相同的负载下崩溃,尽管集群上运行了2个节点服务,非集群上运行了1个服务

现在我想知道为什么?我做错什么了吗

可能是其他原因导致服务器达到断点?两台服务器都以约800转/秒的速度崩溃

现在我想知道为什么?我做错什么了吗

测试服务器除了执行
res.redirect()
之外,不执行任何操作。如果您的请求处理程序基本上不使用CPU,那么您根本不会受到CPU的限制,也不会从涉及更多CPU中获益。您的集群在处理传入连接时会遇到瓶颈,无论是否使用集群,这些连接都大致相同

现在,将一些重要的CPU使用率添加到请求处理程序中,您应该会得到不同的结果

例如,更改为:

// Add a basic route – index page
app.get('/', function (req, res) {

    // spin CPU for 200ms to simulate using some CPU in the request handler
    let start = Date.now();
    while (Date.now() - start < 200) {}

    res.redirect('http://www.walla.co.il');
});
//添加基本路线–索引页
app.get('/',函数(req,res){
//将CPU旋转200ms,以使用请求处理程序中的一些CPU进行模拟
让我们开始=Date.now();
while(Date.now()-start<200){
reshttp://www.walla.co.il');
});
运行测试是一件很棒的事情,但是您必须小心您正在测试的内容

现在我想知道为什么?我做错什么了吗

测试服务器除了执行
res.redirect()
之外,不执行任何操作。如果您的请求处理程序基本上不使用CPU,那么您根本不会受到CPU的限制,也不会从涉及更多CPU中获益。您的集群在处理传入连接时会遇到瓶颈,无论是否使用集群,这些连接都大致相同

现在,将一些重要的CPU使用率添加到请求处理程序中,您应该会得到不同的结果

例如,更改为:

// Add a basic route – index page
app.get('/', function (req, res) {

    // spin CPU for 200ms to simulate using some CPU in the request handler
    let start = Date.now();
    while (Date.now() - start < 200) {}

    res.redirect('http://www.walla.co.il');
});
//添加基本路线–索引页
app.get('/',函数(req,res){
//将CPU旋转200ms,以使用请求处理程序中的一些CPU进行模拟
让我们开始=Date.now();
while(Date.now()-start<200){
reshttp://www.walla.co.il');
});

运行测试是一件很棒的事情,但是你必须小心你到底在测试什么。

jfriend00所说的是正确的;你实际上没有做足够的举重来证明这一点,然而,你实际上没有分担负担。请看这里:

app.listen(3001);
你不能将两个服务绑定到同一个端口上,让操作系统神奇地平衡它们的负载[1];尝试在
app.listen()
上添加错误处理程序,然后查看是否出现错误,例如

app.listen(3001, (err) => err ? console.error(err));
如果要执行此操作,必须接受主控中的所有内容,然后指示工作人员执行任务,然后将结果再次传递给主控

不过,在节点程序中不这样做通常比较容易;你的前端仍然是限制因素。一种更简单(更快)的方法可能是在应用程序的多个运行实例(即HAProxy或Nginx)前面放置一个专用负载平衡器



[1] :那实际上是个谎言;很抱歉您可以通过在执行初始的
bind
调用时指定
SO\u REUSEPORT
来实现这一点,但是您不能在Node中明确指定,Node也不会为您指定它……因此您不能在Node中指定。

@jfriend00所说的是正确的;你实际上没有做足够的举重来证明这一点,然而,你实际上没有分担负担。请看这里:

app.listen(3001);
你不能将两个服务绑定到同一个端口上,让操作系统神奇地平衡它们的负载[1];尝试在
app.listen()
上添加错误处理程序,然后查看是否出现错误,例如

app.listen(3001, (err) => err ? console.error(err));
如果要执行此操作,必须接受主控中的所有内容,然后指示工作人员执行任务,然后将结果再次传递给主控

不过,在节点程序中不这样做通常比较容易;你的前端仍然是限制因素。一种更简单(更快)的方法可能是在应用程序的多个运行实例(即HAProxy或Nginx)前面放置一个专用负载平衡器



[1] :那实际上是个谎言;很抱歉您可以通过在执行初始的
bind
调用时指定
SO\u REUSEPORT
来实现这一点,但是您不能在节点中明确指定,而节点没有为您指定它……因此您不能在节点中指定。

是否总共有2个节点进程或总共3个节点进程,在cluseryea中需要3个节点进程是3个进程:)事实上我是个懒鬼是总共有2个节点进程还是总共有3个节点进程?因为包括master,你在cluseryea中需要3个节点进程是3个进程:)我是个懒鬼