日期:2014-05-16  浏览次数:20385 次

为什么会有NodeJS之一

更多内容参考我基于NodeJS搭建的新博客:http://ramonblog.cloudfoundry.com/


其实这个问题是最为复杂最为不容易回答的。最开始都只是学习Hello World,然后觉得入门了,开始熟悉了,会用了。但是始终不明白为什么NodeJS会产生,什么时候用NodeJS,用它有什么利弊?尤其是在这个已经各种技术蜂涌而且成熟的时候。经过一段时间的学习,开始反思这些问题。

为什么会有NodeJS

比较笼统的回答是:

  1. NodeJS可以让Javascript提供服务器端的功能,从而使得客户端和服务器端的开发都统一在Javascript之下。明显的就是,对于一个对象,如Person Profile的验证不需要客户端和服务器端实现两套。如Java环境下,服务器端用Java实现验证,在客户端用Javascript实现验证。

  2. NodeJS是基于事件的,不像已有的Web服务器,是基于线程的,即每个请求Request都有一个独立的线程为之服务,这样的情况下一旦同时请求很多,则线程很多,每个线程都需要有各种开销,如内存,CPU等。由于每个请求主要消耗的时间都在访问数据库、文件之类的IO操作,这些操作都是同步的,线程都得等。再则线程之间的切换也是需要时间。总之这种线程模型会导致服务器会变慢。而NodeJS则是事件驱动(event driven),只有一个主进程接收各种请求,每个请求只是简单分配,这个很快,当处理耗时的IO操作时,NodeJS采用异步的方式,也就是说主进程不会等IO操作完成,而是直接返回继续进行请求分配,等IO操作完成的时候再通知主进程进行处理。

对于上面的解释并不能让人信服:

  1. 语言统一有很大的吸引力吗?这么多年下来,服务器端的技术已经相当成熟,譬如Java,很多人已经在各种非常优秀地IDE下非常熟练、高效地使用。而且Java和Javascript都是很容易学习的,尤其时对于优秀的程序员来说,这更加不是问题。即便这个是理由,也有很多其他的方法来解决。譬如用GWS。

  2. 最大的疑问是所谓的事件驱动是如何实现的?对于像Swing之类的UI框架来说,一个事件分发线程负责处理事件分发和画图,还有就是用于处理复杂耗时任务的工作线程,这些线程都是在事件分发线程中新建的,目的是避免事件分发线程消耗太多时间在跟图形界面更新无关的任务处理上,那样会导致界面假死。而对于Swing的事件处理机制,我的感觉是这样的,有一个统一的EventQueue用来存储各种事件,然后事件分发线程只负责分发这些事件以及更新图形界面,但是每个事件对应可能要处理耗时的任务则是新开线程来处理。这么说来线程的总数应该是1+n。对于NodeJS的事件驱动,如果也是用这种方法来实现,那么意味着每个request还是有可能对应一个或者多个线程的。这么看来并不见的比多线程模型要来得效率高。


    有一篇不错的文章http://andrewbrobinson.com/2012/01/27/why-are-event-driven-servers-so-great/对比了基于线程和基于事件模型的Web服务器,但是还是不够深入。至于在Youku上搜到国内关于NodeJS的讨论更加只是泛泛而谈。