首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Node.js在集群中设置工作人员,而不将其放在同一个文件中?

如何使用Node.js在集群中设置工作人员,而不将其放在同一个文件中?
EN

Stack Overflow用户
提问于 2022-05-22 01:49:18
回答 3查看 473关注 0票数 1

我在index.js中有这段代码,基本上没有修改官方的Node.js文档。

代码语言:javascript
复制
const https = require('https');
const fs = require('fs');
const cluster = require('node:cluster');
const numCPUs = require('node:os').cpus().length;
const process = require('node:process');

const livegame = require('./server-livegame');
const matchmaking = require('./server-matchmaking');

//Start ExpressJS
var express = require('express');
const { match } = require('assert');

var app = express();
app.use(express.json());


if (cluster.isPrimary) {
  console.log(`Primary ${process.pid} is running`);

  for (let i = 0; i< numCPUs; i++){
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
  });
}
else
{
  new livegame;
  new matchmaking;
}

下面是一个简化的livegame/ error代码,它会产生错误。

代码语言:javascript
复制
const https = require('https');
const fs = require('fs');
const mongoose = require('mongoose');

//Import Models
const LiveMatch = require('./models/livematch');

//Start ExpressJS
var express = require('express');
const { match } = require('assert');

//Interface Security
var options = {
  key: fs.readFileSync('key.pem', 'utf8'),
  cert: fs.readFileSync('cert.pem', 'utf8')
};

//Server
var httpsServer = https.createServer(options, app);

httpsServer.listen(443);
var app = express();
app.use(express.json());

const chat = 
    {
        puuid: String,
        name: String,
        roleID: String,
        message: String,
    }

app.post(':id/chat', (req,res) => 
{
    //something here
});

我将livegame和.js文件作为单独的index.js文件,并调用该文件以编程方式将它们作为多个实例启动。但是,这是我得到的错误:

代码语言:javascript
复制
node:events:505
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE: address already in use :::443
    at Server.setupListenHandle [as _listen2] (node:net:1380:16)
    at listenInCluster (node:net:1428:12)
    at Server.listen (node:net:1516:7)
    at C:\Users\----\Documents\MG\src\server-matchmaking.js:25:66
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Emitted 'error' event on Server instance at:
    at emitErrorNT (node:net:1407:8)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  code: 'EADDRINUSE',
  errno: -4091,
  syscall: 'listen',
  address: '::',
  port: 443
}

根据我到目前为止的进展情况,我认为问题在于我创造了更多的“用餐空间”,而不是雇佣更多的“员工”。

如何使用集群正确地创建具有适当负载平衡的服务器实例?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-05-22 04:27:39

虽然我可能不使用集群,但我是如何修复这段代码的。

代码语言:javascript
复制
const https = require('https');
const fs = require('fs');
const cluster = require('node:cluster');
const numCPUs = require('node:os').cpus().length;
const process = require('node:process');

const livegame = require('./server-livegame');
const matchmaking = require('./server-matchmaking');

//Start ExpressJS
var express = require('express');
const { match } = require('assert');

var app = express();
app.use(express.json());


if (cluster.isPrimary) {
  console.log(`Primary ${process.pid} is running`);

  for (let i = 0; i< numCPUs; i++){
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
  });
}
else
{
  var httpsServer = https.createServer(options, app);
  httpsServer.listen(443);

  livegame(app);
  matchmaking(app);

}

与livegame/相亲相关的看起来像

代码语言:javascript
复制
const https = require('https');
const fs = require('fs');
const mongoose = require('mongoose');

//Import Models
const LiveMatch = require('./models/livematch');

//Start ExpressJS
var express = require('express');
const { match } = require('assert');

this.serverLiveGame = function(app)
{

    const chat = 
    {
        puuid: String,
        name: String,
        roleID: String,
        message: String,
    }

    app.post(':id/chat', (req,res) => 
    {

    });
};

module.exports = this.serverLiveGame;

代码中有不止一个错误:

  1. 只能有一个express()函数来处理给定服务器的API。对于在同一端口下运行的任何相关API,此值应该是常量。在我的实现中,我只是将变量作为参数传递给函数。
  2. 为了将api正确地从另一个.js传递给worker方法,它们必须作为一个带有适当module.exports的模块传递。我把必要的代码包装在一个函数中,所以我只需要在每个api中调用一件东西。
  3. ,因为我们调用的是一个函数,而不是创建一个新的对象,"new“是不正确的。我们将其称为function(param);

的任何其他函数。

谢谢你的帮助!

票数 0
EN

Stack Overflow用户

发布于 2022-05-22 02:33:02

在nodejs中,按其定义,集群是一组进程,所有这些进程都是为了处理相同的传入连接而设置的。主进程使用一种算法在各种集群进程之间旋转传入连接,以便每个进程都得到处理传入连接的转轮。当您需要增加用于处理传入http请求的CPU数量时,通常会使用此方法。默认情况下,单个nodejs进程只在单个线程/CPU中运行Javascript。

而且,根据定义,这些集群进程都在执行与您在主进程中所做的相同事情(处理传入的http请求)。

如果您真正想要的是运行不同的代码(假设您将执行一些繁重的映像处理),并且您正确地希望将繁重的CPU处理从主线程中移出,以便它能够对传入的连接保持响应,那么您可以使用WorkerThread (同一进程中的更多线程)或child_process (更多的进程)。在这两种情况下,您可以在WorkerThread或child_process中运行任何您想要的代码,并且它可能与您在主要nodejs程序中所做的完全不同。

如果根本问题是您在web服务器上的POST处理程序中所做的某些处理,那么您是否需要研究上述任何一种扩展方式完全取决于您在该POST处理程序中所做的事情。Nodejs本身具有异步I/O模型(用于网络、文件I/O、数据库访问等)可以在不涉及额外线程或进程的情况下处理大量同步请求。在nodejs中,编写得当的异步代码扩展得非常好。

因此,除非您的进程大量使用CPU (如我在前面使用的图像处理示例中所述),那么您应该首先编写好的异步代码,看看它是如何工作的,也许还需要对其进行负载测试,以找出瓶颈所在。您可能确实会发现,您的瓶颈是内部瓶颈(因此您可以获得相当高的规模),或者它们不在一个可以从上述附加流程中受益的地方,您需要解决瓶颈的具体原因。对于任何高规模的设计,您首先实现基础,然后仪器在规模上了解您的瓶颈,再次测量,工作瓶颈,再次测量,等等。

猜测您的瓶颈所在通常非常容易出错,这会导致您将软件工程放在错误的位置。别猜了。测试,测量,发现瓶颈,处理瓶颈。冲洗,泡沫,重复。

票数 3
EN

Stack Overflow用户

发布于 2022-05-22 02:14:46

建立在@krtee的帖子上:

这里的核心问题是,实际上您试图在同一个端口上创建多个进程。

这是真的,而且您非常接近这个节点的文档!

代码语言:javascript
复制
// essentially all this stuff 
var httpsServer = https.createServer(options, app);

httpsServer.listen(443);
var app = express();
...

 // needs to go in the `else` block of the worker initialization

...
  for (let i = 0; i< numCPUs; i++){
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died`);
  });
}
else
{
  // right bout here.
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72334287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档