Javascript NodeJS集群,真的需要吗?
我决定研究使用NodeJS服务器处理大量流量的最佳方法,我在2台具有1GB RAM/2 CPU的digital ocean服务器上做了一个小测试 没有群集服务器代码: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
// 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个进程:)我是个懒鬼