10

我刚开始在 node.js 中编码一段时间。现在这是我的一个问题:

在 HTTP 应用程序中,给定请求-响应模型,单个应用程序线程被阻塞,直到所有后端任务完成并将响应返回给客户端,因此性能改进似乎仅限于微调后端之类的东西并行化 IO 请求。(好吧,当涉及到许多繁重独立的 IO 操作时,这种改进很重要,但通常情况还意味着,通过重新设计数据结构,您可以消除大量 IO 请求,并且可能最终获得更好的性能而不仅仅是发出并行操作。

如果这是真的,它怎么能产生比那些基于 Java(或 PHP、python 等)的框架更好的性能呢?

我还参考了一篇文章Understanding the node.js event loop,也说明了这种情况:

它确实是一个单线程运行:你不能做任何并行代码执行;例如,做一个“睡眠”会阻塞服务器一秒钟:

while(new Date().getTime() < now + 1000) {
   // do nothing
}

…然而,除了你的代码之外,一切都是并行运行的。

我个人通过将确切的“睡眠”代码放入一个 IO 回调闭包中验证了这一点,并尝试提交导致此回调的请求,然后提交另一个。这两个请求在处理时都会触发控制台日志。我的观察是后者被阻止,直到前者返回响应。

那么,这是否意味着只有在双方都可以随时发出事件和相互推送消息的套接字模式下,才能发挥其异步处理能力的全部威力呢?

我对此有点困惑。欢迎任何意见或建议。谢谢!

更新

我问这个问题是因为报告了一些性能评估案例,例如Node.js 正在接管企业——不管你喜欢与否LinkedIn 从 Rails 迁移到 Node:27 台服务器削减和高达 20 倍的速度。一些激进的观点声称 J2EE 将被完全取代:J2EE 已死:由 JSON 服务支持的长寿 Javascript

4

3 回答 3

7

NodeJS 使用 libuv,所以 IO 操作是非阻塞的。是的,您的 Node 应用程序使用 1 个线程,但是,所有 IO 请求都被推送到事件队列。那么当请求发出时,很明显它的响应不会在零时刻从socket、文件等中读取。因此,队列中准备好的任何内容都会弹出并进行处理。同时,您的请求可以得到答复,可能有要读取的块或完整数据,但它们只是在队列中等待处理。这一直持续到没有事件剩余,或者打开的套接字被关闭。然后 NodeJS 终于可以结束它的执行了。

如您所见,NodeJS 不像其他框架,完全不同。如果你有一个长期的非 IO 操作,所以它是阻塞的,比如矩阵操作,图像和视频处理,你可以生成另一个进程并分配给他们工作,使用消息传递,你喜欢 TCP,IPC 的方式。

NodeJS 的主要目的是删除不必要的上下文切换,这会在不正确使用时带来巨大的开销。在 NodeJS 中,为什么需要上下文切换?所有作业都被推送到事件队列,并且它们的计算量可能很小,因为它们所做的一切都是为了产生多个 IO/s,(从数据库读取、更新数据库、写入客户端、写入裸 TCP 套接字、从缓存读取),在中间阻止他们并转向另一份工作是不合逻辑的。所以在 libuv 的帮助下,任何一个准备好的 IO 都可以立即执行。

如需参考,请查看 libuv 文档:http ://nikhilm.github.io/uvbook/basics.html#event-loops

于 2013-04-27T23:50:39.613 回答
1

与 Java 相比,我还注意到很多关于 Node.js 性能的激进观点。从排队论的角度来看,我怀疑一个没有阻塞的单个线程如何能够执行多个阻塞的线程。我想我会自己调查一下 Node.js 与更成熟和成熟的技术相比的表现如何。

我通过在 Node.js 和 DropWizard / Java 中编写功能相同的多数据源微服务来评估 Node.js,然后对两个实现进行相同的负载测试。我收集了两个测试结果的性能测量结果并分析了数据。

与 DropWizard 相比,Node.js 的代码大小只有五分之一,延迟相当,吞吐量低 16%。

我可以看到 Node.js 是如何吸引早期初创公司的。在 Node.js 中快速编写微服务并使其运行比使用 Java 更容易。随着公司的成熟,他们的重点往往会从寻找适合的产品/市场转向提高规模经济。这或许可以解释为什么更成熟的公司更喜欢具有更高可扩展性的 Java。

于 2017-02-26T18:55:49.250 回答
-2

就我对 node.js 的经验(虽然简短)而言,我同意 node.js 服务器的性能无法与其他 web 服务器(如tomcat 等)进行比较,如 node.js doc 某处所述

它确实是一个单线程运行:你不能做任何并行代码执行;例如,做一个“睡眠”会阻塞服务器一秒钟:

所以我们用它不是像tomcat这样成熟的网络服务器的替代品,而只是为了分散来自tomcat的一些负载,我们可以在其中采用单线程模型。所以它必须在某个地方进行权衡

另请参阅http://www.sitepoint.com/node-js-is-the-new-black/那是关于 node.js 的漂亮文章

于 2013-04-27T15:20:23.093 回答