繁体   English   中英

Nodejs + Express + Cluster如何使用同一端口?

[英]Nodejs+Express+Cluster How to use same port?

因此,我正在尝试集群并遇到“错误:bind EADDRINUSE null”。

压缩(和测试)代码:

var cluster = require('cluster');
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();
}
} else {
    var https = require('http');
    var express = require('express');
    var app = express();
    var serv = https.createServer(app);
    serv.listen(80);
    console.log("Server started.");
}

显然是因为我的工人绑定到同一端口。 与客户端的连接是连续的,并且有点密集。 我想负载平衡入站连接到工人。 我的主人可以通过什么方式与工人建立联系?

我已经整理了一下Express样板,但这是通常的想法:

var app = require('../app');
var http = require('http');
var cluster = require('cluster');

var port = process.env.PORT || '3000';
app.set('port', port);

// Code to run if we're in the master process
if (cluster.isMaster) {

  var cpuCount = require('os').cpus().length;

  // Create a worker for each CPU
  for (var i = 0; i < cpuCount; i += 1) {
      cluster.fork();
  }

} else {
  var server = http.createServer(app);
  server.listen(port);
  server.on('listening', onListening);
}

cluster.on('exit', function(worker) {
  console.log('Worker ' + worker.id + ' died :(');
  cluster.fork();
});

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
    console.log('Listening on ' + bind);
}

此处的主要区别是var app = require('../app'); 在顶部。

app导出一个Express实例。 您正在为每个工人创建一个。

尝试将代码重新安排为:

var cluster = require('cluster');
var https = require('http');
var express = require('express');
var app = express();

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();
    }
} else {
    var serv = https.createServer(app);
    serv.listen(80);
    console.log("Server started.");
}

重要的是

var serv = https.createServer(app);
serv.listen(80);

使每种形式的服务器都在端口80上侦听-而不是创建单独的app实例,所有实例都试图在该端口上进行绑定和侦听,从而导致EADDRINUSE错误。

另外,如果您正在使用pm2进程管理器,则可以使用PM2集群。 除此之外,ngnix代理服务器还可以充当负载平衡器。

好吧,第一个答案是正确的。 但我希望您对集群有所了解。 将您的应用程序集群化或分支为多个进程的概念并不意味着在不同的端口上运行多个应用程序。 实际上,这个概念是分布。

很快,假设您的应用程序仅通过一个进程在端口3000上运行。 为了使其能够承担更多的负载或将负载分配到多个进程中,我们进行了集群。 因此,我认为您很清楚,不应在此之后出现其他端口问题。

所以是的,第一个答案是正确的,无论哪种方式,您都可以自己做,PM2。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM