Node.js 什么时候会阻塞?

2023-11-22

我已经使用 Node.js 一段时间了,我刚刚意识到它可能会阻塞。我就是无法理解 Node.js 在什么情况下会发生阻塞。

  • 因此,Node.js 是单线程的,因为 (i) Javascript 是并且 (ii) 避免了所有多线程陷阱。
  • 要同时做很多事情,尽管是单线程的, 实现异步执行。因此,与 DB(I/O 一般来说)是非阻塞的(因为它是异步的)。
  • 但是,所有传入的请求都要做一些工作(即与数据库交谈)并且 该工作的所有结果必须返回给客户端(即发送 一些数据)他们使用那个单线程。
  • Node.js 使用该单线程内的“事件循环”来获取所有 请求并将它们分配给非阻塞 I/O 任务。

因此,由于异步回调,I/O 任务是非阻塞的,但单线程可能会阻塞,因为它是同步的,并且事件循环可能会因为同时出现大量复杂的请求而被堵塞?

  1. 我对吗,我理解正确吗?我想我不会因为here and here他们强调“Node 是单线程的 这意味着您的代码没有并行运行”。这实际上是什么 是什么意思以及它如何使 Node 阻塞?
  2. 因此,事件循环永远运行并始终搜索请求,或者 它在发现新请求后开始执行?
  3. Node 的阻塞弱点是否会导致 Node 对于大型应用程序毫无用处? 项目并使其最终仅适用于微型站点和 小项目?

多谢。


首先,要明确:node.js 作为一个整体isn't单线程。 Node 确实有一个通过 libuv 的线程池,它用来执行一些目前在大多数平台上无法通过单个线程有效完成的任务(例如文件 I/O),或者它们本质上是计算密集型的(例如 zlib)。应该指出的是,大多数crypto模块(本质上也是计算密集型的)当前没有异步/非阻塞接口(除了crypto.randomBytes()).

v8 还利用多线程来执行垃圾收集、函数优化等操作。

然而,节点中的几乎所有其他内容都发生在同一个单线程中。

现在具体解答您的问题:

  1. JavaScript 代码是从单个线程运行的事实不会造成节点阻塞。作为这个答案解释说,节点最重要的是(I/O)并发性而不是(代码)并行性。你could利用内置的并行运行节点代码cluster例如,在多核/CPU 系统上,节点的主要目标是能够同时处理大量 I/O,而无需为每个套接字/服务器/等专用一个线程。

  2. 有一篇不错的,详细的here它描述了节点中的事件循环是如何工作的。

  3. 如前所述,Node 的主要目标是很好地处理 I/O,这适合 Web 应用程序和任何类型的网络程序的大多数用例。

    如果您的脚本受 CPU 限制(例如,您正在计算 pi 或转码音频/视频),那么您最好将该工作委托给节点中的子进程(例如,调用ffmpeg用于转码,而不是在 javascript 中进行或在节点主线程上的 C++ 节点插件中同步进行)。你could如果您同时不执行任何其他操作(例如处理 HTTP 请求),则在进程中执行这些阻塞操作。许多人会以这种方式使用 Node 来执行 I/O 并发性并不那么重要的各种实用任务。其中一个示例可能是执行 js 和 css 文件缩小、linting 和/或捆绑的脚本,或者从大量图像创建缩略图的脚本。

    但是,如果您的脚本创建了一个 TCP 或 HTTP 服务器,例如从数据库中提取信息、对其进行格式化并将其发送回用户,则节点将擅长执行此操作,因为大部分时间都花费在该过程中只是等待套接字/HTTP 客户端发送(更多)数据并等待数据库回复查询结果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node.js 什么时候会阻塞? 的相关文章

随机推荐