在 NodeJs 中,为什么我最后一个分叉的工作进程每次都处理请求,尽管 7 个工作进程仍然是理想的?

In NodeJs, Why my last forked worker process handle request every time, Although 7 worker process remain ideal?

我想使用集群模块 运行 使用工作进程并排表示服务器。这是我的完整脚本。

const express = require('express');
const cluster = require('cluster');
const os = require('os');


const totalCPUs = os.cpus().length;
const PORT = 3000;


if (cluster.isMaster) {

  console.log(`Number of logical cpus is available: ${totalCPUs}`);

  console.log(`Master ${process.pid} is running`);

  // Fork workers
  for (let i = 0; i < totalCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
    console.log("Let's fork another worker!");
    cluster.fork();
  });
} else {

  const app = express();
  console.log(`Worker ${process.pid} started`);
  app.get('/', (req, res) => {
    res.send(`Performance example: ${process.pid} `);
  });

  function spin(duration) {
    const startTime = Date.now();

    while (Date.now() - startTime < duration) {
      // block the event loop
    }
  }
  app.get('/delay', (req, res) => {
    // after some delay
    spin(9000);
    res.send(`Ding ding ding! ${process.pid}`);
  });

  app.listen(PORT, () => {
    console.log(`Worker process ${process.pid} Listening on ${PORT}`);
  });
}

每当我在浏览器中打开多个选项卡并点击相同的 http://localhost:3000/delay api 然后所有请求 运行 仅由最后创建的子进程串联。我将如何使用保留所有子进程?

如果您从浏览器发出多个完全相同的请求,那么浏览器本身可能会保留您的第二个请求,直到第一个请求 returns(可能希望使用缓存的结果)。如果你想打败这个浏览器“功能”,你可以为每个 URL 添加一个唯一的查询参数,如下所示:

const mainUrl = "http://localhost:3000/delay";
const uniqueUrl = mainURL + "?r=" + Math.random();

然后,将您的请求从浏览器发送到uniqueUrl。这将防止浏览器序列化它们以希望使用以前缓存的结果。为您从浏览器发送的每个请求生成一个新的 uniqueUrl

你的服务器会忽略查询参数,但是浏览器会认为每个 URL 是不同的,因此不会让第二个等待第一个响应等等,让你得到一些请求并行到同一条路线。请记住,浏览器仍然有关于它将向同一主机发出多少同时请求的规则,因此您仍然不一定会并行获得所有请求,但您应该获得一些。


或者,使用单独的实际客户端发送每个请求,这样单个浏览器客户端就不会阻止您。

或者,从客户端(如 nodejs 客户端测试应用程序)发送多个请求,该客户端不执行浏览器执行的“保留缓存”。