一般来说,Node.js如何处理10,000个并发请求?

我知道Node.js使用单线程和事件循环来处理一次仅处理一个请求的请求(这是非阻塞的)。但是,这是如何工作的,可以说有10,000个并发请求。事件循环会处理所有请求吗?那会不会花费太长时间?

我还不了解(至今)如何比多线程Web服务器更快。我知道多线程Web服务器的资源(内存,CPU)会更昂贵,但是会不会更快?我可能错了;请说明在处理大量请求时此单线程的速度如何,以及在处理诸如10,000之类的大量请求时通常会执行的操作(高级)。

而且,单线程是否可以很好地扩展?请记住,我才刚刚开始学习Node.js。

十三小卤蛋2020/03/18 15:05:18

slebetman的答案:当您说Node.JS可以处理10,000个并发请求时,它们本质上是非阻塞请求,即这些请求主要与数据库查询有关。

在内部,event loopNode.JS受理的thread pool,其中每个线程处理一个non-blocking request和事件循环继续委托工作的线程之一后,听取更多的要求thread pool当其中一个线程完成工作时,它会向发出信号,event loop表明它也已完成callbackEvent loop然后处理此回调并将响应发送回去。

当您刚接触NodeJS时,请阅读更多有关内容nextTick以了解事件循环在内部如何工作的信息。阅读http://javascriptissexy.com上的博客,当我开始使用JavaScript / NodeJS时,它们对我真的很有帮助。

Green西里2020/03/18 15:05:18

slebetman的答案中添加了更多信息,使您更清楚地了解执行代码时发生的情况。

默认情况下,nodeJs中的内部线程池只有4个线程。并且它并不像整个请求都从线程池中附加到新线程一样,整个请求的执行就像任何普通请求一样(没有任何阻塞任务),就像每当一个请求有长时间运行或诸如db这样的繁重操作时一样调用,文件操作或http请求,任务将排队到libuv提供的内部线程池中。而且,由于nodeJs默认在内部线程池中提供4个线程,因此每5个或下一个并发请求将等待直到一个线程空闲,并且一旦这些操作结束,回调便被推入回调队列。并由事件循环接收并发回响应。

现在出现了另一个信息,它不是曾经有一个回调队列,而是有很多队列。

  1. NextTick队列
  2. 微任务队列
  3. 计时器队列
  4. IO回调队列(请求,文件操作,数据库操作)
  5. IO轮询队列
  6. 检查阶段队列或SetImmediate
  7. 关闭处理程序队列

每当请求到来时,代码都将按此回调顺序排队执行。

它不像有阻止请求时,它被附加到新线程上。默认情况下只有4个线程。因此,那里还有另一个排队正在发生。

每当在代码中发生诸如文件读取之类的阻塞过程时,然后调用一个利用线程池中的线程的函数,然后在完成该操作后,将回调传递到相应的队列,然后按顺序执行。

一切都会根据回调的类型排队,并按上述顺序进行处理。

小卤蛋伽罗2020/03/18 15:05:18

Single Threaded Event Loop Model Processing Steps:

  • Clients Send request to Web Server.

  • Node JS Web Server internally maintains a Limited Thread pool to provide services to the Client Requests.

  • Node JS Web Server receives those requests and places them into a Queue. It is known as “Event Queue”.

  • Node JS Web Server internally has a Component, known as “Event Loop”. Why it got this name is that it uses indefinite loop to receive requests and process them.

  • Event Loop uses Single Thread only. It is main heart of Node JS Platform Processing Model.

  • Event Loop checks any Client Request is placed in Event Queue. If not then wait for incoming requests for indefinitely.

  • 如果是,则从事件队列中选择一个客户端请求

    1. 开始客户要求的流程
    2. 如果该客户端请求不需要任何阻塞IO操作,则处理所有内容,准备响应并将其发送回客户端。
    3. 如果该客户请求需要某些阻止IO操作(例如与数据库,文件系统,外部服务进行交互),则它将采用不同的方法
  • 从内部线程池检查线程可用性
  • 拾取一个线程并将此客户请求分配给该线程。
  • 该线程负责处理该请求,处理该请求,执行阻塞IO操作,准备响应并将其发送回事件循环

    @Rambabu Posa很好地解释了更多解释,请抛出此链接

斯丁小宇宙猿2020/03/18 15:05:18

您似乎想的是,大多数处理是在节点事件循环中进行的。节点实际上将I / O工作分配给线程。I / O操作通常比CPU操作花费几个数量级,那么CPU为什么要等待呢?此外,操作系统已经可以很好地处理I / O任务。实际上,由于Node不等待它,可以提高CPU利用率。

以此类推,可以将NodeJS看作是服务员,在I / O厨师在厨房里准备客户时接受客户的订单。其他系统有多位厨师,他们接一位顾客的订单,准备饭菜,清理桌子,然后再拜访下一位顾客。