在处理原始计算任务方面,Node.js并不比Java快;一旦涉及到IO型任务,Java就没有竞争力了。也就是说,在典型的Web应用程序执行的任务类型场景中,Node.js运行速度确实比Java更快。
为了更好的理解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时间都将用于服务请求上。