工作人员可能是我的节点应用程序在生产中崩溃的主要原因吗?

问题描述 投票:0回答:1

我们正在 AWS 上测试 Node.js 后端,但在使用某些需要较长时间的工具后,我们的应用程序不断崩溃。我们有实施人员,但我不知道他们是否导致了这次崩溃。我读到,对于异步 I/O 操作,工作线程的实现可能会使应用程序效率更低、速度更慢。我们有连接到 python 微服务的端点,它们执行一些 Web 抓取并返回一些 json。这比正常的请求要多一点,但不是这个世界之外的东西,我说的是毫秒,甚至是第二个差异。

这个问题自从我们部署后端以来已经有一周左右了。首先,我们认为这是子进程,因为我们通过子进程调用python脚本,所以我们决定将它们分开实现微服务。部署新的微服务后,我们注意到这些抓取功能得到了优化,但主要问题并没有解决。我们的应用程序有时仍然会崩溃。

我们使用 EC2 免费套餐,并且只能访问 2 个处理器核心(2 个工作线程)。帮助我看看我是否走在解决这个问题的正确道路上。如果我们只使用后端来处理异步请求(I/O 操作),则不需要工作人员,这将成为一个低效的解决方案。我认为作为团队,我们对这些工作人员的使用存在误解,他们并不代表对我们后端请求的任何类型的优化。

这是我们的app.js,主要微服务的核心:

require('dotenv').config(); // Environment variables.
const cluster = require('cluster');
const { availableParallelism } = require('os');

// If the current process is the master process
if (cluster.isMaster) {
  // Get the number of available CPUs
  const numCPUs = availableParallelism();

  // Create workers according to the number of CPUs
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // Handle exit events of workers
  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} exited with code: ${code} and signal: ${signal}`);
    console.log('Creating a new worker...');
    cluster.fork(); // Create a new worker to replace the exited one
  });

  // Get the number of workers
  const numWorkers = Object.keys(cluster.workers).length;
  console.log(`Number of workers: ${numWorkers}`);
} else {
  // If the current process is a worker process
  const morgan = require('morgan');
  const express = require('express');
  const session = require('express-session');
  const compression = require('compression');
  const cors = require('cors');
  const hpp = require('hpp');
  const lusca = require('lusca');
  const helmet = require('helmet');
  const rateLimit = require('express-rate-limit');
  const config = require('./src/config');

  // ==== Route Imports ==== //
  // Health checker
  const healthRouter = require('./src/routes/healthCheck');

  // Initialize the App.
  const app = express();

  // Configure session and cookies.
  app.use(session(config.sessionConfig));

  // Global Variables.
  app.set('port', process.env.PORT || 3001);

  // Global Configurations.
  app.use(morgan('dev')); // Dev displays info in a semi-condensed manner.
  app.use(cors(config.corsOptions)); // Implement and configure CORS.
  app.use(express.urlencoded({ extended: false })); // Middleware to decode form data (application/x-www-form-urlencoded).
  app.use(express.json()); // Middleware to parse JSON formatted request bodies.

  // Add hpp middleware.
  app.use(hpp());
  // Add express-rate-limit middleware.
  app.use(rateLimit(config.rateLimitConfig)); // Apply rate limit to all requests.
  // Add Lusca middleware.
  app.use(lusca(config.luscaOptions)); // Apply Lusca configurations.
  // Add Helmet middleware.
  app.use(helmet(config.helmetOptions)); // Apply Helmet configurations.

  // Add compression middleware.
  app.use(compression(config.compressionOptions.default));

  // ==== Routes ==== //

  // Enable proxy
  if (process.env.ENABLE_TRUST_PROXY) {
    app.enable('trust proxy');
  }

  // Check if the server is running.
  app.listen(app.get('port'), () => {
    console.log(`Worker ${process.pid} running on port: ${app.get('port')}`);
  });
}

注意:当我的意思是我们的应用程序崩溃时,我的意思是我们的整个实例都崩溃了(不仅仅是我们的微服务的容器),所以这就是为什么我认为工作人员的实现是问题所在。在迁移到 docker compose 和微服务之前也是如此。

node.js express web-worker node-worker-threads
1个回答
0
投票

是的,如果没有有效实施,工作人员可能会导致您的 Node 应用程序崩溃,尤其是在资源有限的 EC2 免费套餐实例上。监控资源使用情况和优化工作策略至关重要。

使用流程管理器:

#install pm2
npm install -g pm2

#start cluster mode
pm2 start app.js -i max

检查系统限制:

Ulimit:确保您的实例未达到打开文件或进程的限制。您可以在 /etc/security/limits.conf 中检查并增加这些限制。

* soft nofile 1024
* hard nofile 4096
© www.soinside.com 2019 - 2024. All rights reserved.