为什么在Express Node JS中同时请求相同的路由时群集不起作用?

时间:2019-08-27 06:58:37

标签: node.js express httprequest cluster-computing

我写了一个简单的快速应用程序示例,处理2条GET路由。第一条路径包含一个while循环,代表5秒钟内的阻塞操作。 第二种方法只是返回Hello World文本。

我还按照Node JS文档中的简单指南设置了集群。

我尝试过的结果:

  1. 同时向2条不同的路由发出2个请求=>它们按预期独立工作。路线/花费了5秒钟,路线/ hello花费了几毫秒。

  2. 同时向同一路径/发出2个请求=>它们同步工作,一个在5秒后响应,另一个在10秒后响应。

const cluster = require("cluster");
const express = require("express");
const app = express();

if (cluster.isMaster) {
  cluster.fork();
  cluster.fork();
} else {
  function doWork(duration) {
    const start = Date.now();

    while (Date.now() - start < duration) {}
  }

  app.get("/", (req, res) => {
    doWork(5000);
    res.send("Done");
  });

  app.get("/hello", (req, res) => {
    res.send("Hello world");
  });

  app.listen(3000);
}

我希望它将并行处理2个相同路由的请求。谁能解释发生了什么事?

2 个答案:

答案 0 :(得分:1)

  

我希望它将并行处理2个相同路由的请求。能够   有人解释发生了什么事吗?

情况并非如此,因为您已经创建了两个服务器实例(使用cluster.fork()的两个事件循环),所以每个请求都在不同的事件循环(服务器实例)和{{1}中执行}会提示您,而/hello的请求仍要等待5秒钟才能发送响应。

现在,如果您尚未创建集群,那么/请求将阻止事件循环,直到事件循环执行(将响应发送到浏览器)/为止。< / p>

/hello将花费5秒钟的时间执行,因为您阻止了它在其中执行的事件循环,因此无论创建单个事件循环还是两个事件循环(使用fork()),它都会在5秒钟后执行< / p>

我在两个不同的浏览器中尝试了您的情况,两个请求都花了5.05秒(两者均由不同的工作线程同时执行)

/

但是在相同的浏览器中,请求始终转到一个工作线程,该线程仅在第一次执行后才执行第二个请求,因此我猜想所有有关请求如何在cluster.fork()创建的工作线程之间分配的信息

引自node docs

  

集群模块支持两种分配传入数据的方法   连接。

     

第一个(在Windows以外的所有平台上都是默认的),   是循环方法,其中主进程侦听   港口,接受新的联系并将其分配给工人   以循环的方式,避免使用一些内置的智能   重载工作进程。

     

第二种方法是主进程创建监听的地方   套接字并将其发送给感兴趣的工作人员。工人然后接受   直接传入连接。   Node.js不提供路由逻辑。因此,重要的是   设计一个应用程序,使其不会过于依赖   内存数据对象,用于会话和登录之类的东西。

答案 1 :(得分:0)

我运行了您的代码,第一个响应是在5秒钟后发出的,另一个响应是在8秒钟后发出的,因此集群正在工作。使用以下代码找出计算机的内核数。如果是,那么只有一个主线程。

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