NodeJS集群,真的需要吗?
NodeJS cluster, Is it really needed?
我决定要研究用 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
时崩溃
Now i wonder why ? did i do anything wrong?
您的测试服务器除了 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');
});
运行 测试是一件好事,但你必须小心你测试的到底是什么。
@jfriend00 说的对;您实际上并没有做足够的繁重工作来证明这一点,但是,您实际上并没有分担负担。看这里:
app.listen(3001);
您不能将两个服务绑定到同一个端口并让 OS 神奇地对它们进行负载平衡[1];尝试在 app.listen()
上添加错误处理程序并查看是否出现错误,例如
app.listen(3001, (err) => err ? console.error(err));
如果你想这样做,你必须接受你的主人的一切,然后指示工人做任务,然后再把结果传回给主人。
虽然在您的 Node 程序中不通常更容易做到这一点;您的前端仍然是限制因素。一种更简单(也更快)的方法可能是在应用程序的多个 运行 实例(即 HAProxy 或 Nginx)之前放置一个特殊用途的负载均衡器。
[1]:这其实是个谎言;对不起。您 可以 通过在执行初始 bind
调用时指定 SO_REUSEPORT
来执行此操作,但您不能在 Node 中明确指定它,并且 Node 不会指定它对你来说...所以你不能在 Node.
我决定要研究用 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
时崩溃Now i wonder why ? did i do anything wrong?
您的测试服务器除了 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');
});
运行 测试是一件好事,但你必须小心你测试的到底是什么。
@jfriend00 说的对;您实际上并没有做足够的繁重工作来证明这一点,但是,您实际上并没有分担负担。看这里:
app.listen(3001);
您不能将两个服务绑定到同一个端口并让 OS 神奇地对它们进行负载平衡[1];尝试在 app.listen()
上添加错误处理程序并查看是否出现错误,例如
app.listen(3001, (err) => err ? console.error(err));
如果你想这样做,你必须接受你的主人的一切,然后指示工人做任务,然后再把结果传回给主人。
虽然在您的 Node 程序中不通常更容易做到这一点;您的前端仍然是限制因素。一种更简单(也更快)的方法可能是在应用程序的多个 运行 实例(即 HAProxy 或 Nginx)之前放置一个特殊用途的负载均衡器。
[1]:这其实是个谎言;对不起。您 可以 通过在执行初始 bind
调用时指定 SO_REUSEPORT
来执行此操作,但您不能在 Node 中明确指定它,并且 Node 不会指定它对你来说...所以你不能在 Node.