Node 如何保持服务器进程处于活动状态?

2024-02-23

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

看着the code https://github.com/nodejs/node/blob/master/lib/net.js and 一个不完整的旧答案 https://stackoverflow.com/questions/41137902/how-does-server-listen-keep-the-node-program-running,它最终调用self._listen2()它发出一个“监听”事件process.nextTick,并从中获取异步钩子 IDDefaultTriggerAsyncId().

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

Thanks!


真正的答案终于来自伯特·贝尔德 https://www.youtube.com/watch?v=PNa9OMajw9w,他从事 libuv 工作。

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

那么,服务器会发生什么?这个确切的过程,除了监听函数不会减少引用计数器。事件循环看到总是至少有一个剩余的引用,因此它永远不会结束该过程,而是返回到开始并循环,直到发生新的事情。

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

const http = require("http");

    http
      .createServer((req, res) => {
        res.writeHead(200);
        res.end("Bye bye");
      })
      .listen(3333)
      .unref();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node 如何保持服务器进程处于活动状态? 的相关文章

随机推荐