【问题标题】:How does Node keep a server process alive?Node 如何让服务器进程保持活动状态?
【发布时间】:2018-12-26 12:37:33
【问题描述】:

当 Node 的事件循环完全耗尽时,进程存在。然而,这不会发生在例如 HTTP 服务器上,因为 server.listen()。但是那个函数到底是做什么的呢?

查看the codean old incomplete answer,它最终调用self._listen2(),它在process.nextTick 上发出一个“监听”事件,并从DefaultTriggerAsyncId() 获取一个异步挂钩ID。

但是,我还是不明白。我在这里想念什么?仅此代码如何导致事件循环保持“空闲”?函数在 C 端是如何包装的?实际执行此操作的代码行在哪里?

谢谢!

【问题讨论】:

    标签: node.js server process


    【解决方案1】:

    真正的答案finally came from Bert Belder,从事libuv工作。

    每次 Node 排队一个动作,该动作将在未来的某个时间解决,想想异步函数或计时器,它都有一个 ref——一个标记来提醒自己它正在等待一些未来的工作。事件循环检查是否有任何 refs。如果 ref 计数器为 0 ,则 Node 退出进程。如果有 refs,事件循环会回到开始并做它的事情。你可以把它想象成一个超级简单的while(refCounter)循环。

    那么,服务器会发生什么?这个确切的过程,除了监听函数不会递减 ref 计数器。事件循环看到总是至少剩下一个 ref,所以它永远不会结束进程,而是回到开始并循环,直到发生新的事情。

    您可以通过在带有 net 或 http 模块的服务器对象上使用 server.unref() 来查看这一点。 unref 方法在其他对象上也可用,它告诉 Node 在事件循环结束时计数时忽略该特定函数的 ref。如果你运行下面的代码,你会看到 Node 关闭了进程,即使它开始监听端口。

    const http = require("http");
    
        http
          .createServer((req, res) => {
            res.writeHead(200);
            res.end("Bye bye");
          })
          .listen(3333)
          .unref();
    

    【讨论】:

      【解决方案2】:

      让我在这里解释几个步骤: 1.您在特定端口上启动服务器,它的作用是“它启动一个服务器进程,该进程运行类似于

      while(true){
         readdatafromport();
         if(unhandledexceptionHappened){
            killtheServerProcess();
           }
       }
      

      除非发生异常,否则它会一直读取。如果发生异常,它会终止服务器进程,并且您的 HTTP 服务器会关闭或死机。

      1. 当下面的代码执行时:

         server.listen()
        

        如果有任何新数据来到这里,它只是注册监听端口。在 TCP/IP 中,当客户端调用服务器时,他们基本上将他们的请求写在服务器 PORT 上(我这样说是为了便于解释)。由于服务器处理正在侦听端口的变化,它可以对此做出响应。如果您了解节点事件的工作原理,希望您了解服务器进程如何同时管理许多请求。

      【讨论】:

      • 感谢您的回答,但除了问题之外。我在问为什么 Node 不退出带有 server.listen 的进程,以及该函数如何与事件循环交互。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-12
      • 2016-06-21
      • 2015-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多