当前位置: 首页 > 面试题库 >

通常,Node.js如何处理10,000个并发请求?

潘宸
2023-03-14
问题内容

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

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

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


问题答案:

如果您必须问这个问题,那么您可能不熟悉大多数Web应用程序/服务的功能。您可能会认为所有软件都可以这样做:

user do an action
       │
       v
 application start processing action
   └──> loop ...
          └──> busy processing
 end loop
   └──> send result to user

但是,这不是Web应用程序或任何以数据库为后端的应用程序的工作方式。Web应用程序可以这样做:

user do an action
       │
       v
 application start processing action
   └──> make database request
          └──> do nothing until request completes
 request complete
   └──> send result to user

在这种情况下,软件将大部分运行时间都用0%的CPU时间来等待数据库返回。

多线程网络应用程序:

多线程网络应用程序可以像这样处理上述工作量:

request ──> spawn thread
              └──> wait for database request
                     └──> answer request
request ──> spawn thread
              └──> wait for database request
                     └──> answer request
request ──> spawn thread
              └──> wait for database request
                     └──> answer request

因此,线程大部分时间都使用0%的CPU等待数据库返回数据。这样做时,他们不得不分配一个线程所需的内存,其中每个线程都包括一个完全独立的程序堆栈。此外,他们还必须启动一个线程,尽管它并不像启动一个完整的进程那样昂贵。贱。

单线程事件循环

由于我们大部分时间都使用0%的CPU,为什么不使用CPU时不运行一些代码?这样,每个请求仍将获得与多线程应用程序相同的CPU时间,但是我们不需要启动线程。所以我们这样做:

request ──> make database request
request ──> make database request
request ──> make database request
database request complete ──> send response
database request complete ──> send response
database request complete ──> send response

实际上,这两种方法都以大致相同的延迟返回数据,这是因为数据库响应时间决定着处理的时间。

这里的主要优点是我们不需要产生新的线程,因此我们不需要执行大量的malloc会减慢我们的速度。

魔术隐形螺纹

看似神秘的事情是上述两种方法如何设法以“并行”方式运行工作负载?答案是数据库是线程化的。因此,我们的单线程应用程序实际上是在利用另一个进程的多线程行为:数据库。

单线程方法失败的地方

如果您需要在返回数据之前进行大量CPU计算,则单线程应用程序会失败很大。现在,我不是说要for循环来处理数据库结果。仍然大部分是O(n)。我的意思是像执行傅立叶变换(例如,mp3编码),光线跟踪(3D渲染)等。

单线程应用程序的另一个陷阱是,它将仅利用单个CPU内核。因此,如果您拥有四核服务器(当今并不常见),则您不会使用其他3个核。

多线程方法失败的地方

如果您需要为每个线程分配大量RAM,则多线程应用程序会失败很大。首先,RAM本身的使用量意味着您无法处理与单线程应用程序一样多的请求。更糟糕的是,malloc很慢。分配大量对象(这在现代Web框架中很常见)意味着我们可能最终会比单线程应用程序慢。这是node.js通常获胜的地方。

一个最终导致多线程恶化的用例是,当您需要在线程中运行另一种脚本语言时。首先,通常需要为该语言分配整个运行时,然后需要分配脚本使用的变量。

因此,如果您使用C或html" target="_blank">go或java编写网络应用程序,则线程的开销通常不会太糟。如果您要编写C网络服务器来服务PHP或Ruby,那么用javascript或Ruby或Python编写更快的服务器非常容易。

混合方式

某些Web服务器使用混合方法。例如,Nginx和Apache2将其网络处理代码实现为事件循环的线程池。每个线程运行一个事件循环,同时处理单线程请求,但请求在多个线程之间进行负载平衡。

一些单线程体系结构还使用混合方法。您可以启动多个应用程序,而不是从一个进程启动多个线程,例如,在四核计算机上启动4个node.js服务器。然后,您可以使用负载平衡器在各个进程之间分配工作负载。

实际上,这两种方法在技术上是彼此相同的镜像。



 类似资料:
  • 有一个场景,1000个请求要求redis获取名为goods_stock的密钥,同时在redis中设置该密钥的vaule等于goods_stocks-1,redis服务器如何处理这些请求?它是否处理默认队列,就像每个请求都是块请求一样?

  • 问题内容: 我有一个关于单例bean如何详细处理并发请求的问题。 我想要有关单例bean如何处理并发请求以及系统处理器如何看到这些请求的完整详细信息。 我已经研究了有关在线处理系统处理器中并发请求的问题。他们说处理器本身有一个调度程序,调度程序将决定处理哪个请求。 好的。如果假设我有多个核心处理器,那么调度程序如何处理并发请求? 谁能向我解释有关单例bean如何为JVM和系统中的并发请求提供服务的

  • 我正在使用Spring Boot构建一个RESTful web服务。我的IDE是Eclipse Oxygen。 这里是我的控制器代码: 我的控制台输出是: 控制台输出显示每5秒调用一次控制器。但我每隔两秒就发送一次请求。 是否可以接受来自同一会话的并发多个请求? 谢谢!

  • 并发请求处理 我创建了一个服务器,并使用s.listenandserve()来处理请求。据我所知,这些请求是同时送达的。我使用一个简单的处理程序来检查它: 我看到,如果我发送了几个请求,我将看到所有的“1”出现,只有在一秒钟后所有的“2”出现。但是如果删除Hibernate行,我会看到程序在完成前一个请求之前从不启动请求(输出为1 2 1 2 1 2...)。所以我不明白,如果它们是并发的还是不是

  • 问题内容: 假设我有某种游戏。我有一个buyItem函数,如下所示: 如果我对该路由进行垃圾邮件处理,直到扣除用户余额(第二次查询),则用户余额仍为正。 我尝试过的 问题是将在第一〜5项要求。因此,这也不起作用。 我们如何处理这种情况?如果重要的话,我正在使用Sails.JS框架。 问题答案: 通过该方法,Sails 1.0现在具有完整的事务支持。例: 更新资料 正如一些评论者所指出的,启用连接池

  • 问题内容: 我对Go如何处理Google App Engine上的并发请求感到困惑。所以我希望有人可以提供一些清晰度。 这是我收集的事实: 1.Goroutine被多路复用到多个OS线程上,因此,如果一个应阻塞,例如在等待I / O时,其他将继续运行。 [[App Engine]的并发限制为10个[通过每个运行时的并发线程限制来实施]。 如果Go在App Engine上是单线程的,则第3点没有意义