Node 如何保持服务器进程的存活状态?



当 Node 的事件循环完全耗尽时,该进程存在。但是,例如,由于server.listen(),这不会在HTTP服务器上发生。但是这个功能到底有什么作用呢?

查看代码和一个旧的不完整答案,它最终调用self._listen2()process.nextTick发出"侦听"事件,并从DefaultTriggerAsyncId()获取异步钩子 ID。

但是,我仍然不明白。我在这里错过了什么?仅此代码如何导致事件循环保持"空闲"状态?函数如何包装在 C 端?实际执行此操作的代码行在哪里?

谢谢!

真正的答案最终来自从事libuv工作的Bert Belder。

每次 Node 排队一个将在将来某个时间点解决的操作时,想想异步函数或计时器,它都有一个 ref – 一个标记来提醒自己它正在等待未来的工作。事件循环检查是否有任何引用。如果 ref 计数器为 0 ,则 Node 退出进程。如果有 ref,事件循环将返回到起点并执行其操作。您可以将其视为一个超级简单的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();

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

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

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

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

    server.listen()
    

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

最新更新