在HTTP模式下,Node.js相比Java有明显的性能优势吗?

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回调函数中,并尝试提交请求来引导此回调函数,然后再提交另一个请求。当处理时,两个请求都会触发控制台日志。我的观察是,后者被阻塞直到前者返回响应。

所以,这是否意味着只有在socket模式下,双方可以随时发出事件并推送消息,才能充分利用其异步处理能力的全部功能?

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

更新

我提出这个问题是因为有一些性能评估案例,例如Node.js正在接管企业——无论您喜欢与否,以及LinkedIn从Rails转向Node:减少了27台服务器,速度提高了20倍。一些激进的观点声称,J2EE将被完全替换:J2EE已死:长命JavaScript,由JSON支持的服务


1
你从哪里得到这个想法,认为它有任何性能优势,更别说“实质性”的优势了? - user207421
@EJP据报道,在某些情况下,例如[Node.js正在接管企业-无论您喜欢与否](http://blog.appfog.com/node-js-is-taking-over-the-enterprise-whether-you-like-it-or-not/)和[LinkedIn从Rails转移到Node:切割27个服务器并提高20倍速度](http://highscalability.com/blog/2012/10/4/linkedin-moved-from-rails-to-node-27-servers-cut-and-up-to-2.html)。一些激进的观点声称,J2EE将被JavaScript + JSON服务完全取代(http://java.dzone.com/articles/j2ee-dead-long-live-javascript) - coderLMN
3个回答

7
NodeJS使用libuv,因此IO操作是非阻塞的。是的,您的Node应用程序只使用1个线程,但是所有IO请求都被推送到事件队列中。然后当请求被发出时,显然它的响应不会立即从套接字、文件等读取。因此,准备好的内容都在队列中等待处理。同时,可以回答您的请求,可能有数据块或完整数据需要读取,但它们只是在队列中等待处理。这将一直持续到没有事件剩余或打开的套接字已关闭。然后NodeJS最终可以结束其执行。
正如您所看到的,NodeJS与其他框架不同,相当不同。如果您有长时间运行和非IO操作(如矩阵操作、图像和视频处理),则它是阻塞的,可以生成其他进程并将其分配给作业,使用消息传递,以您喜欢的方式TCP、IPC。
NodeJS的主要目标是消除不必要的上下文切换,这在不正确使用时会带来重大开销。在NodeJS中,为什么要进行上下文切换?所有工作都被推送到事件队列中,它们可能在计算上较小,因为它们所做的只是进行多个IO/s(从数据库读取、更新数据库、写入客户端、写入裸TCP套接字、从缓存读取),在中途停止并切换到另一个作业是不合逻辑的。因此,在libuv的帮助下,任何准备好的IO都可以立即执行。
请参考libuv文档:http://nikhilm.github.io/uvbook/basics.html#event-loops

应用程序可以初始化多个并行的IO任务,但这不是问题所在。我的担忧是,在HTTP模式下,它必须等待所有后端事情完成后才能响应,然后才能处理另一个请求。 - coderLMN
“在HTTP模式下,必须等待所有后端事情完成才能处理另一个请求”这种说法不是正确的 - 这正是Node.js的优势所在。当第一个请求正在等待IO操作完成时,Node.js可以开始/继续处理其他请求。” - Matt Browne
基本上,Node 使得不浪费任何 CPU 时间成为可能,而这在 IO 操作是同步的情况下是不可能的。正如 @RoelvanUden 所提到的,通过每个核心拥有一个 Node 进程,您可以充分地最大化性能。 - Matt Browne

1
我也注意到了一些关于Node.js性能与Java相比的激进观点。从排队理论的角度来看,我对一个没有阻塞的单线程如何胜过多个被阻塞的线程持怀疑态度。因此,我决定进行调查以了解Node.js与更成熟的技术相比表现如何。
我编写了一个功能完全相同的多数据源微服务,并在Node.js和DropWizard / Java中分别实现,然后将两个实现都提交给相同的负载测试。我收集了两个测试结果的性能测量数据并进行了分析。
代码大小只有DropWizard的五分之一,Node.js的延迟时间可比,并且吞吐量比DropWizard低16%。
我可以看出为什么Node.js在初创公司中越来越受欢迎。使用Node.js编写微服务比使用Java更快,并且更容易使其运行起来。随着公司的发展,它们的重心往往会从寻找产品/市场适应性转向提高规模经济效益。这可能解释了为什么更成熟的公司更喜欢具有更高可扩展性的Java。

-2

就我的经验而言(尽管很短),我同意 node.js 服务器的性能不能与其他网络服务器如 tomcat 等进行比较,这在 node.js 的文档中某处已经说明了。

它确实是单线程运行的:您无法执行任何并行代码;例如执行“sleep”将会阻止服务器一秒钟:

因此,我们使用它不是作为像 tomcat 这样的完整 web 服务器的替代品,而只是为了从 tomcat 中分担一些负载,在那里我们可以采取单线程模型。因此必须在某个地方做出权衡。

还请参见http://www.sitepoint.com/node-js-is-the-new-black/ 这是有关 node.js 的精彩文章


1
您可以将进程分组,每个核心使用一个进程,从而有效地利用所有可用资源。 - Deathspike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接