Java与Node.js性能PK

866 阅读9分钟

原文链接:www.tandemseven.com/b...

如果你打开浏览器,搜索“Java与Node.js哪个更快”,你会发现大部分答案声称Node.js更快,也有一些人持相反意见。Java使用JIT编译器,其性能甚至可以超过C++。在这种情况下,为什么这么多人还是声称Node.js要比Java快呢?小编现在就跟大家一起往下看。

实际检验结果

实际上,在处理原始计算任务方面,Node.js并不比Java快;一旦涉及到IO型任务,Java就没有竞争力了。也就是说,在典型的Web应用程序执行的任务类型场景中,Node.js运行速度确实比Java更快,在接下来模拟的4种场景测试的结果充分验证了这一点。

性能因素

为了更好的理解Node.js如何完胜Java,需要考虑到3个性能因素:IO,并发和计算。这三大因素对于提高应用程序的整体运行速度和吞吐量都是有影响的。

1、IO

根据servlet规范,Java在早几年前引入的NIO实际上是Java编写后端服务器代码的标准。在整个规范中,servlet API都假定代码可以并且将在每个级别阻塞。虽然过去几年规范有所改进,能够允许非阻塞请求处理,但servlet规范的基本范例仍然完全包含IO阻塞。这意味着以非阻塞方式写入磁盘或使用JDBC写入数据库的操作会阻止处理线程执行任何其他操作。虽然Java能够以非阻塞的方式工作,但是对于基于servlet技术的Java应用程序来说,实现一个非阻塞服务器仍然是不切实际的。对于Java社区来说,这一点是非常遗憾。

另一方面,JavaScript完全支持非阻塞IO。JavaScript API不提供阻塞选项,在每个级别上强制支持非阻塞API规范。这意味着在执行IO操作时,Node将永远不会被阻塞,并且在等待IO时,Node将始终可以自由地处理其他工作。从而,Node能够非常高效地使用服务器的处理和内存资源。具体来说,Node只需一个线程就可以同时处理和发出数千个IO操作。

2、并发

在Web框架中,Java和Node以两种截然不同的方式实现并发。

Java:它为处理的每个传入请求指定一个线程。随着并发请求数的增加,线程数也必须增加。如果计划同时处理最多100个请求,则需要有100个线程池可供处理。

Node:使用一个线程来处理所有传入的请求。由于Node是非阻塞的,它有足够的时间对所有请求执行所有计算和转换,同时等待任何IO操作。

3、计算

虽然谷歌的V8 JavaScript引擎将JavaScript编译成机器代码,这结果让人印象深刻。但是,在某些场景中,Java是优于Node的。比如,您要让Java与Node进行纯计算PK,计算前5000个素数,那么Java每次都会轻松获胜。

Java与Node.js性能PK

Web应用程序执行大量的IO。首先,从浏览器接受请求;这是IO操作。其次,应用程序通常从数据库中获取请求的数据;这也是IO操作。一旦计算出所有响应数据,应用程序就会将响应数据发送回浏览器;这也是IO操作。应用程序可能一直都在维护日志;这还是IO操作。实际上,Web应用程序大部分时间都花在IO操作上,而不是计算。

对于Web应用程序而言,它为每个请求提供服务,需要执行大量的IO,对比之下,Node要比Java更加的适合。

Web应用程序需要高并发

通常,一个Web应用程序有很多个用户同时访问。基于Java必须为每个请求的生命周期指定一个线程,所以它需要大量线程来实现并发。如果在同一时间,应用程序的访问用户增加,那么在所有这些线程之间进行时间分割,很快就会变得非常昂贵并且低效。最终,随着线程数量的增加,操作系统忙着在所有线程之间进行切换,将变得非常繁忙,以至于CPU时间爆满后无法做任何实际工作。

这种大规模的情况下,Node的效率就很明显了。当Node以最大负载运行时,虽然CPU会非常繁忙,但操作系统能够轻松自如的应付。所有的CPU时间都将用于服务请求上。

Java与Node性能PK模拟

为了证明Node确实可以超越Java,本文介绍了4种场景,在这些场景中通过使用模拟器来测试这两种技术的性能。此模拟器的代码,大家可以通过下面的链接找到:

github.com/johnrjenso...

注释:

本测试中,为Java实现模拟阻塞IO。有些人可能会认为使用阻塞IO并不公平地比较Java的性能,但在本测试中使用阻塞IO的原因如下:①Java的JDBC规范仍然是一个阻塞规范,这意味,每当有人使用标准JDBC驱动程序连接到关系数据库时,都必须阻塞。② Apache Tomcat 8.5在2016年6月才完成了第一个非阻塞Servlet规范,这意味着绝大多数生产Java应用程序在执行IO时仍会阻塞。因此,由目前大多数组织以阻塞的方式使用Java,所以在本次模拟中,阻塞也是最具有代表性的Java。

Java与Node.js性能PK

在第一个场景中,选择一个纯计算工作负载来证明Java的计算优势。分别在有和没有并发的情况下进行测试模拟,工作负载情况:

1a:①无并发;②计算500个质数;③执行0个阻塞IO调用。

1b:①有并发;②计算500个质数;③执行0个阻塞IO调用。

测试结果如下:

1a:纯计算任务在没有使用并发时,Java速度是Node的2.1倍左右;

1b:一旦将并发加入到任务中,Java领先Node的速度降低到1.8倍。

场景2:大量IO操作

第二种模拟中,不做任何计算工作,只执行IO任务。分别在有和没有并发的情况下进行测试模拟,工作负载情况如下:

2a:①无并发;②计算0个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

2b:①有并发;②计算0个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

结果如下:

2a:没有并发时,Node的速度是Java的3.4倍;

2b:有并发时,Node的速度增加到Java的8.5倍。添加并发后,Node与Java之间的差异更加明显。

场景3:均衡的工作负载

此场景与典型Web应用程序的请求工作负载最接近,模拟中同时执行IO和计算任务,均衡工作负载。同样,也是在有和没有并发的情况下分别模拟。

工作负载情况:

3a:①无并发;②计算500个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

3b:①有并发;②计算500个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

测试结果:

3a:没有并发时,Node的速度是Java的1.8倍;

3b:有并发时,Node的速度增加到Java的4.9倍。

场景4:长时间运行的查询

工作负载情况:

①计算500个质数;②发出一个很长的阻塞IO调用——10s响应时间;③处理一个5MB文件

测试结果:

Java每秒6个请求;Node每秒64个请求,是Java的10倍

观察结果能够发现,执行长时间运行的查询,Java运行的性能大大受影响,但相同场景下,Node的性能几乎没有降低。也就是说,Node完胜Java。

结论

在典型Web应用程序的真实场景中,Node确实是比Java运行速度更快、更具可伸缩性。对于Web应用程序开发来说,Node的性能是难以比拟的。由于Web应用程序大部分时间都在做IO,并且需要高并发,相比之下,Node显然是最终的赢家。

关于Node.js的性能指标

1、事件循环

事件循环意味着能够在队列中执行代码。事件循环能让Node.js执行非阻塞IO操作。因此,服务器可以处理无限数量的操作。系统可以处理异步操作。事件循环这个指标衡量事件处理延迟。

2、实时用户行为

实时用户行为指的就是用户(客户)在使用应用程序时所做的事情。举个例子,Uber或Netflix用户可在几秒钟内完成业务交易,这就反映出了了Node.js的效率。实时用户行为这个指标是测量响应时间的。

3、外部框架

Node.js应用程序也同样依赖于其他的服务、系统和数据库。它可能会连接到其他应用程序,缓存等,因此也必须记住这戏依赖关系。通过这些外部框架,可以检查应用程序的响应时间,请求率,错误率,内容大小,API,等等。

4、进程内存

Node.js有一个很棒的助手工具——垃圾收集器,它管理应用程序的内存并防止内存泄漏。首先,您可以测量在GC上花费的时间——运行越多次,系统中的暂停次数也就越多。其次,还可以比较每次运行时的内存并检查构建趋势。

Node.js的优点

Node.js是一种非阻塞事件驱动模型,它能够让开发人员实时构建应用程序。通过推送技术和双向连接,许多大企业都在使用它。那么,使用Node.js都有哪些好处呢?

小编跟大家一起来看下:

1.速度(在Google JS引擎上运行);

2.非阻塞I/O模式

3.数据流(HTTP请求和响应作为的单个事件)

4.实时应用(客户端和服务器端)

5.统一的数据库查询(JSON格式)

6.编码简单快速

7.开源NPM存储库(超过600000个模块)

8.代理服务器能力

9.快速的开发周期

10.服务器上的业务逻辑

11.适用于Android设备