在HTTP模式下,node.js是否比Java具有显着的性能优势?

时间:2013-04-27 14:58:25

标签: java performance node.js sockets http

我刚开始在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 模式下,双方都可以随时发送事件并相互推送消息,是否会充分利用其异步处理能力? / p>

我对此感到有些困惑。欢迎提出任何意见或建议。谢谢!

更新

  

我问这个问题是因为一些绩效评估案例是   举报,例如Node.js is taking over the Enterprise – whether you like it or not,   和LinkedIn Moved from Rails to Node: 27 Servers Cut and Up to 20x Faster。   一些激进的观点声称J2EE将被完全取代:J2EE is Dead: Long-live Javascript Backed by JSON Services

3 个答案:

答案 0 :(得分:7)

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

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

NodeJS的要点是删除不正确的上下文切换,如果使用不当会带来很大的开销。在NodeJS中,您为什么要上下文切换?所有作业都被推送到事件队列,它们的计算量可能很小,因为他们所做的只是做多个IO / s,(从db读取,更新db,写入客户端,写入裸TCP套接字,从缓存读取),将它们停在中间并切换到另一个工作是不合逻辑的。因此,在libuv的帮助下,现在可以执行任何已准备就绪的IO。

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

答案 1 :(得分:1)

与Java相比,我也注意到了很多关于Node.js性能的激进观点。从排队论的角度来看,我怀疑没有阻塞的单个线程如何能够执行阻塞的多个线程。我认为我会自己investigation进行Node.js对更成熟和成熟技术的表现。{/ p>

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

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

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

答案 2 :(得分:-2)

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

  

它实际上是一个单独的线程运行:你不能做任何并行代码   执行;例如,进行“休眠”将阻止服务器进行一次   第二:

所以我们使用它不是像tomcat那样完全成熟的网络服务器的替代品,而只是从tomcat中分配一些负载,我们可以采用单线程模型。所以它必须在某处进行权衡

另见http://www.sitepoint.com/node-js-is-the-new-black/这是关于node.js的漂亮文章