nodejs - 为啥 Node.js 可以处理大量的同时持久连接?
Posted
技术标签:
【中文标题】nodejs - 为啥 Node.js 可以处理大量的同时持久连接?【英文标题】:nodejs - Why Node.js can handle large number of simulteneous persistent connections?nodejs - 为什么 Node.js 可以处理大量的同时持久连接? 【发布时间】:2012-05-20 18:05:26 【问题描述】:我知道 Node.js 擅长保持大量同时的持久连接,例如,可以容纳许多聊天者的聊天室。
我想知道它是如何做到这一点的。我的意思是无论如何它使用的是由底层操作系统封装的 TCP/IP,为什么它可以很好地处理持久连接而其他人不能?
它有什么神奇之处?
【问题讨论】:
@MartinJames:我认为我们已经离开了 JS 是脚本小子领域的时代。无需讽刺语言学家的言论。 @Amadan OP 问题即将成为商业推广。这听起来不像是“基于所面临的实际问题的实用、可回答的问题”,(常见问题解答)。语言学家的评论似乎很合适。我没有否决它或投票结束,因为它有可能是一个真正的问题。 @MartinJames:不,如果您觉得某个问题不属于 SO,那么指向常见问题解答的指针是合适的,而不是那样。如果问题是关于node.cs,你会以同样的方式回答吗? @Amadan - 当然不是!我会找到其他一些讽刺语言学家的回复。 @MartinJames 我不同意你的看法,我的问题有点像business promotion
。我问这个是因为我真的很想知道为什么人们都选择 node.js 来实现同时持久连接,而异步技术不再是秘密。我对 node.js 了解不多,但希望了解和了解更多。这就是为什么我问这个general
的问题,而不是specific
的问题。但这并不意味着我不被允许,对吧?有时您可能希望在深入了解之前先了解一下概况,对吧?
【参考方案1】:
Node.js 使所有 I/O 异步。它只在单个线程中运行,但会在等待 I/O 时执行其他请求或操作。
相比之下,经典网络服务器在前一个请求完全完成之前不会处理另一个请求。为此,Apache 同时运行多个进程;假设有 10 个httpd
进程,这通常意味着可以同时处理 10 个请求 (*)。如果流程需要更多时间来完成,您将提供更少的请求 - 或者将不得不产生更多的流程,即使该流程什么都不做 - 比如等待数据库咀嚼并返回数据。
一个 node.js 进程,面对一个将进入数据库的请求,让数据库继续工作,同时它去服务另一个请求。
*) MPM 使这并不完全正确,但对于所有意图和目的来说都足够正确。
【讨论】:
我很好奇,如果 Node.js 只是使用非阻塞 IO,为什么 Apache 等其他巨头无法生产出这样一个非阻塞的东西呢?为什么httpd不改成这种框架?他们可以吗? 安全。 Apache 做得很好;将请求彼此隔离是其中的一部分。但是,当您不想隔离请求时,Apache 并不能很好地处理它;尽管 Phusion Passenger 和 FastCGI 有所帮助。请记住:Apache 主要服务于静态页面;其他一切都通过 CGI 或插件(Apache 模块)。因此,为 I/O 优化 Apache 就像为拉车优化鹅一样。 (另一方面,当谈到 Ruby 或 Python 时,两者都可以通过各自的异步库 - EventMachine 或 Twisted 来做 node.js 所做的事情。)【参考方案2】:嗯,问题是大多数 Web 服务器(如 apache 等)都使用线程生成,它们为每个传入的 HTTP 请求生成一个新线程。这些线程本质上是同步和阻塞的 => 这意味着它们将按照编写的顺序执行代码,并且任何进一步的计算都将被当前的 I/O 或计算任务阻塞。就像如果你想听一个事件一样 - 聊天者的聊天提交,你需要每个用户有一个专用线程(每个用户是维持持久连接所必需的,几乎没有可能的优化技术,但你仍然可以假设线程是用户)监听这个事件,这个线程将被阻塞等待这个事件发生。所以对于任何线程产生和阻塞网络服务器
另一方面,javascript 本质上是非阻塞的(并且可用于异步代码)=> 在这里您为事件注册一个回调,并且每当它发生时,都会执行一些回调函数。它不会在任何时候阻塞等待这个事件。
您可以通过阅读有关非阻塞或异步服务器的信息来了解更多信息。
【讨论】:
JavaScript 不是异步的,node.js 是。由于函数的一等公民身份,JavaScript 非常适合异步编码风格(或者更确切地说,延续传递风格);但 JavaScript 本身并没有什么特别异步的。以上是关于nodejs - 为啥 Node.js 可以处理大量的同时持久连接?的主要内容,如果未能解决你的问题,请参考以下文章