Node.js 何时阻塞? [英] When is Node.js blocking?

查看:18
本文介绍了Node.js 何时阻塞?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 Node.js 有一段时间了,我才意识到它可能会阻塞.我只是无法将我的大脑包裹在 Node.js 成为阻塞的条件下.

I have used Node.js for a while now and I just realized it can be blocking. I just cannot wrap my brain around the conditions under which Node.js becomes blocking.

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

所以 I/O 任务是非阻塞的,因为异步回调,但是单线程可以阻塞,因为它是同步的,并且因为同时出现大量复杂请求而导致事件循环阻塞?

So the I/O tasks are non-blocking because of asynchronous callbacks, but the single thread can be blocking, because it's synchronous and because the event loop can be jammed because a lot of complicated requests showing up at the same time?

  1. 我是对的,我理解正确吗?我想我不是因为这里这里 他们强调节点是单线程的这意味着您的代码都没有并行运行".那实际上是什么是什么意思以及它是如何使节点阻塞的?
  2. 因此,事件循环永远运行并始终搜索请求,或者它在发现新请求后开始执行?
  3. Node 阻塞的弱点是否会导致 Node 无法用于大项目并使其最终仅适用于微型网站和小项目?
  1. Am I right, did I understand this correctly? I, guess I don't because here and here they emphasize that "Node is single-threaded which means none of your code runs in parallel". What does that actually mean and how does it make Node blocking?
  2. So, the event loop runs forever and always searches for requests, or it starts execution after it spots a new request?
  3. Does the Node blocking weakness renders Node useless for big projects and make it eventually suitable for only micro-sites and small projects?

非常感谢.

推荐答案

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

First, to be clear: node.js as a whole isn't single-threaded. Node does have a thread pool via libuv that it uses to perform some tasks that are either currently impossible to do efficiently from a single thread on most platforms (e.g. file I/O) or they are inherently computation intensive (e.g. zlib). It should be noted that most of the crypto module (which would also be inherently computation intensive) currently does not have an async/non-blocking interface (except for crypto.randomBytes()).

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

v8 also utilizes multiple threads to do things like garbage collection, optimization of functions, etc.

然而,node 中的几乎所有其他事情都发生在同一个单线程中.

However just about everything else in node does occur within the same, single thread.

现在具体解决您的问题:

Now to address your questions specifically:

  1. javascript 代码从单个线程运行这一事实不会导致节点阻塞.正如this answer所解释的,节点最重要的是(I/O)并发而不是(代码)并行.您可以利用内置的 cluster 模块并行运行节点代码,例如在多核/cpu 系统上,但节点的主要目标是能够处理大量 I/O 并发,每个套接字/服务器/等没有专用一个线程.

  1. The fact that the javascript code is ran from a single thread doesn't make node block. As this answer explains, node is foremost about (I/O) concurrency rather than (code) parallelism. You could run node code in parallel by utilizing the built-in cluster module for example on a multi-core/cpu system, but node's primary goal is to be able to handle a lot of I/O concurrently without dedicating one thread per socket/server/etc.

有一篇很好的详细文章 here 描述节点中的事件循环是如何工作的.

There is a good, detailed writeup here that describes how the event loop in node works.

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

Node's primary goal as previously described is to handle I/O really well, which fits with the majority of use cases for web applications and any kind of network programs for example.

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

If your script is CPU-bound (e.g. you're calculating pi or transcoding audio/video), you are probably better off delegating that work to a child process in node (e.g. calling out to ffmpeg for transcoding instead of doing it in javascript or synchronously in a c++ node addon on node's main thread). You could do these blocking things in-process if you aren't doing anything else at the same time (like handling HTTP requests). There are many people who will use node in this way for performing various utility tasks where I/O concurrency isn't as important. One example of this might be a script that performs minification, linting, and/or bundling of js and css files or a script that creates thumbnails from a large set of images.

但是,如果您的脚本改为创建一个 TCP 或 HTTP 服务器,例如从数据库中提取信息、对其进行格式化并将其发送回用户,那么 node 将很擅长这样做,因为大部分时间花费在在这个过程中只是等待套接字/HTTP客户端发送(更多)数据并等待数据库回复查询结果.

However, if your script instead creates a TCP or HTTP server for example that pulls information from a database, formats it, and sends it back to the user, then node will be good at doing that because the majority of the time spent in the process is just waiting for sockets/HTTP clients to send (more) data and waiting for the database to reply with results from queries.

这篇关于Node.js 何时阻塞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆