代码之家  ›  专栏  ›  技术社区  ›  Daniel Santos

如何让express Node.JS在繁重的工作负载中回复请求?

  •  0
  • Daniel Santos  · 技术社区  · 6 年前

    POST 到我的服务器并使用 GET

    这是我的简化代码

    // Configure Express
    const app = express();
    app.listen(8080);
    
    // Console
    app.post('/clean, async function(req, res, next) {
    
        // start proccess
        let result = await worker.process(data);
    
        // Send result when finish
        res.send(result);
    });
    
    // reply with when asked
    app.get('/clean, async function(req, res, next) {
        res.send(worker.status);
    });
    

    问题是。服务器在网络上工作很辛苦 POST /clean 处理那个 GET /clean 没有及时答复。

    请求在工作进程完成任务并释放处理器来响应请求后得到响应。

    enter image description here

    换句话说。应用程序在工作负载期间无法响应。

    2 回复  |  直到 6 年前
        1
  •  1
  •   jfriend00    6 年前

    因为node.js以单线程的方式运行Javascript(一次只运行一段Javascript),并且不划分时间,只要 worker.process() 正在运行同步代码,服务器无法处理其他请求。这就是为什么 worker.process() 必须在运行get serviced时到达的任何http请求之前完成。node.js事件循环一直忙到 这样它就不能服务于任何其他事件(比如传入的http请求)。

    以下是解决这个问题的一些方法:

    1. 使用内置的集群模块对应用程序进行集群,这样您就有了一系列可以处理的进程 编码或处理传入的http请求。

    2. 什么时候该打电话 worker.process() ,启动一个新的node.js进程,在那里运行处理,并用标准进程间通信返回结果。然后,主node.js进程保持读取状态,以便在传入的http请求到达时立即处理它们。

    3. 创建一组额外的node.js进程的工作队列,这些进程运行放入队列中的作业,并将这些进程配置为能够运行 worker.process() 来自队列的代码。这是#2的一个变体,它限制进程的数量并将工作序列化到队列中(比#2更好地控制)。

    4. 重做的方式 执行它的工作,以便它可以一次执行几毫秒的工作,然后返回到消息循环,以便其他事件可以运行(如传入的http请求),然后再继续它的工作,一次执行几毫秒。这通常需要构建某种有状态的对象,这种对象每次被调用时都可以做一点工作,但要有效地编程往往是一件痛苦的事情。

    请注意,#1、#2和#3都要求在其他过程中完成工作。这意味着 process.status()

        2
  •  1
  •   Jacob    6 年前

    除了将您的服务转换为一个进程集群或使用类似于实验性的东西之外,没有任何办法解决JS的单线程特性 Worker Threads

    function workPart1() {
      // Do a bunch of stuff
      setTimeout(workPart2, 10); 
    }
    function workPart2() {
      // More stuff
      setTimeout(workPart3, 10); // etc. 
    }