【问题标题】:NodeJS cluster, Is it really needed?NodeJS集群,真的需要吗?
【发布时间】:2018-06-11 12:51:13
【问题描述】:

我决定要研究使用 NodeJS 服务器处理大量流量的最佳方法是什么,我在 2 个具有 1GB RAM / 2 个 CPU 的数字海洋服务器上做了一个小测试 无集群服务器代码:

// 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);
}

并且我向这些服务器发送了压力测试请求,我除了集群服务器将处理更多请求但它没有发生,两台服务器在相同的负载下崩溃,虽然集群上运行了 2 个节点服务和 1 个服务在非集群上。

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

也许是其他原因导致服务器到达断点?两台服务器都以约 800 rps 的速度崩溃

【问题讨论】:

  • 是一共2个node进程还是一共3个node进程?,因为包括master,cluser中需要3个node进程
  • 是的,这是 3 个过程 :) 我在事实方面比较懒散

标签: javascript node.js express server node-cluster


【解决方案1】:

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

除了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');
});

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

【讨论】:

    【解决方案2】:

    @jfriend00 说的是正确的;您实际上并没有做足够的繁重来证明这一点,但是,您实际上并没有分担负载。见这里:

    app.listen(3001);
    

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

    app.listen(3001, (err) => err ? console.error(err));
    

    如果你想这样做,你必须接受你的主人的一切,然后指示工人完成任务,然后再次将结果传回主人。

    不过,在您的 Node 程序中执行此操作通常更容易;您的前端仍然是限制因素。一种更简单(更快)的方法可能是在应用程序的多个运行实例(即 HAProxy 或 Nginx)前面放置一个特殊用途的负载均衡器。


    [1]:这实际上是一个谎言;对不起。您可以通过在执行初始 bind 调用时指定 SO_REUSEPORT 来执行此操作,但您不能在 Node 中明确指定它,并且 Node 不会为您指定它...所以您不能在节点中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-09
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 2020-01-29
      • 2014-02-28
      相关资源
      最近更新 更多