NodeJS VS Java EE

Posted 叁言贰拍

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NodeJS VS Java EE相关的知识,希望对你有一定的参考价值。


NodeJS优缺点及适用场景

NodeJS VS Java EE
1. NodeJS特点

先来看看NodeJS官网上的介绍:

Node.js is a platform built on Chrome’s javascript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.

总结一下,NodeJS有以下特点:

1. 它是一个Javascript运行环境

2. 依赖于Chrome V8引擎进行代码解释

3. 事件驱动

4. 非阻塞I/O

5. 轻量、可伸缩,适于实时数据交互应用

6. 单进程,单线程

2. 单线程

目前大概有四种网络编程策略:

  1. 服务器为每个客户端请求分配一个线程/进程,使用阻塞式I/O。Java就是这种策略,Apache也是,这种策略还是很多交互式应用的首选。因为阻塞,这种策略很难实现高性能,但非常简单,可以实现复杂的交互逻辑。

  2. 服务器用一个线程处理所有客户端请求,使用非阻塞的I/O及事件机制。node.js采用的就是这种策略。这种策略实现起来比较简单,方便移植,也能提供足够的性能,但无法充分利用多核CPU资源。

  3. 服务器会分配多个线程来处理请求,但每个线程只处理其中一组客户端的请求,使用非阻塞的I/O及事件机制。这是对第二种策略的简单改进,在多线程并发上容易出现bug。

  4. 服务器会分配多个线程来处理请求,但每个线程只处理其中一组客户端的请求,使用异步I/O。这种策略在支持异步I/O的操作系统上性能非常高,但实现起来很难,主要用在windows平台上。

NodeJS采用第2种。怎么理解这个单线程非阻塞的机制呢?

用“一夫当关”来类比单线程,二爷一把大刀镇守城墙,敌兵上来不是一个一个杀掉,要是来一个杀一个,二爷有天大的本事,城也守不住。怎么办?城里的老弱病残都武装起来,上城墙的敌兵被二爷一个一个扔进城池,锄头棍子锤子一顿乱殴,来不及说再见。二爷就是这里的单线程。

说到这里有人就要问了,多放几个二爷在城墙上岂不是更好?原则是可以的,但问题是没有那么多二爷阿。比如Java, apache, 上来一个敌兵,就有一个守城的士兵等着,敌众我寡,如何能守住。计算机的世界里,多线程处理并发虽然可以提高吞吐量,减少响应时间,但也是有代价的:

设计更复杂:多线程程序在访问共享数据的时候往往需要我们很小心的处理,否则就会出现难以发现的BUG,一般地,多线程程序往往比单线程程序设计会更加复杂(尽管有些单线程处理程序可能比多线程程序要复杂),而且错误很难重现(因为线程调度的无序性,某些bug的出现依赖于某种特定的线程执行时序)。


上下文切换的开销:线程是由CPU进行调度的,CPU的一个时间片内只执行一个线程上下文内的线程,当CPU由执行线程A切换到执行线程B的过程中会发生一些列的操作,这些操作主要有”保存线程A的执行现场“然后”载入线程B的执行现场”,这个过程称之为“上下文切换(context switch)”,这个上下文切换过程并不廉价,如果没有必要,应该尽量减少上下文切换的发生。


增加更多的资源消耗: 除了CPU执行上下文切换的消耗以外,线程的执行还将有其他一些资源的消耗,比如:内存同步的开销(线程需要一些内存在维持线程本地栈,每个线程都有本地独立的栈用以存储线程专用数据),上下文切换的开销(前面已经讲过),线程创建和消亡的开销,以及调度的开销(占用操作系统的一些资源来管理和协调线程)我们可以创建100个线程让他们什么都不做,看看他们消耗了多少内存。

所以也就有了NodeJS所声称的这样一个简单的,处理高并发的单线程编程模型。


3. 非阻塞,事件驱动

NodeJS使用异步I/O和事件驱动(回调函数)解决高并发的问题。二爷何以如此神通广大,这就是异步I/O的威力,一旦城墙上有了阻塞,更多的敌兵上来了,城就破了。二爷所做的的只是把上来敌兵扔回城池,至于是用棍子消灭还是用锤子消灭,二爷不关心,二爷关心的是消灭了,也就是处理后的回调。阻塞I/O为什么不能处理高并发的请求,因为是阻塞的。你这不是放吗,等于没说。是这样的,比如一个聊天程序。为每个在线的用户新建一个线程,用户发了一条信息,在这条信息处理完成之前,下一条信息只能排队,处理这条信息可能比较耗时,要鉴黄鉴反,要传输要存储。相反,基于事件驱动的模型,来了我马上接受请求,处理完再做回调,用户的消息不会在队列里排队。


因为大多数网站的服务器端都不会做太多的计算,它们只是接收请求,交给其它服务(比如文件系统或数据库),然后等着结果返回再发给客户端。所以聪明的Node.js针对这一事实,它不会为每个接入请求繁衍出一个线程,而是用一个主线程处理所有请求。避开了创建、销毁线程以及在线程间切换所需的开销和复杂性。这个主线程是一个非常快速的event loop,它接收请求,把需要长时间处理的操作交出去,然后继续接收新的请求,服务其他用户。

NodeJS VS Java EE


4. NodeJS的缺点

NodeJS目前也有如下的缺点

  1. 不适合计算密集型的应用程序。长事件耗时的计算会导致性能的急剧下降

  2. 不稳定的API

  3. 相对差开发调试工具

  4. 如果不精通NodeJS编程,开发可能并不如想象的那么高,甚至有可能比其他语言更低。


NodeJS VS Java EE

Java EE 平台

相比而言,Java EE不需要做过多的阐述。Java EE在过去二十几年一直统治着服务器端的开发,丰富的类库,强大工程实践和开发生态。绝大多数的企业问题都能在Java中找到解决方案。


基于我自己的理解,我画出了下面这张图,或许可以作为一些互联网产品开发选型的参考,不当之处敬请指正。这种架构既可以利用NodeJS处理高并发的优势,提高开发效率,做到前后端开发分离,又可以充分发挥Java EE平台在企业级解决方案方面的优势。


以上是关于NodeJS VS Java EE的主要内容,如果未能解决你的问题,请参考以下文章

nodejs-配置vs code的插件

nodeJS exports – exports vs module.exports

vs code 调试nodejs项目配置文件

Google chrome vs nodejs(v8)的性能?

vs开发nodejs api文档生成神器-apidoc

VS Code nodejs智能补全typings