1.1 Node.js概述
1.1.1 使用Node.js能够解决什么问题
Node.js的首要目标是提供一种简单的、用于创建高性能服务器及可在该服务器中运行的各种应用程序的开发工具。首先让我们来看一下现在的服务器端语言中存在着什么问题。在Java、PHP或ASP.NET等服务器端语言中,为每一个客户端连接创建一个新的线程,而每个线程需要耗费大约2MB的内存,也就是说,理论上,具有8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而Web应用程序的硬件成本也就随之增加了。不仅如此,在技术层面也会因此产生一些潜在的问题。例如,由于同一个用户的不同客户端请求可能会被不同的服务器处理,因此必须在所有的服务器之间共享所有的资源。由此可见,在一个Web应用程序中,一个主要的瓶颈是服务器所支持的最大同时连接用户量。
Node.js修改了客户端到服务器端的连接方法,解决了这个问题。因为它并不为每个客户端连接创建一个新的线程,而是为每个客户端连接触发一个在Node.js内部进行处理的事件。因此,如果使用Node.js,可以同时处理多达几万个用户的客户端连接。因此,当需要使Web应用程序能够支持大量用户的并发连接的时候,我们应该考虑使用Node.js。
1.1.2 实现高性能服务器
严格地说,Node.js是一个用于开发各种Web服务器的开发工具。在Node.js服务器中,运行的是高性能V8JavaScript脚本语言,该语言是一种可以运行在服务器端的JavaScript脚本语言。
那么,什么是V8JavaScript脚本语言呢?该语言是一种被V8JavaScript引擎所解析并执行的脚本语言。V8JavaScript引擎是由Google公司使用C++语言开发的一种高性能JavaScript引擎,该引擎并不局限于在浏览器中运行。Node.js将其转用在了服务器中,并且为其提供了许多附加的具有各种不同用途的API。例如,在一个服务器中,经常需要处理各种二进制数据。在JavaScript脚本语言中,只具有非常有限的对二进制数据的处理能力,而Node.js所提供的Buffer类则提供了丰富的对二进制数据的处理能力。
另外,在V8JavaScript引擎内部使用一种全新的编译技术。这意味着开发者编写的高端的JavaScript脚本代码与开发者编写的低端的C语言具有非常相近的执行效率,这也是Node.js服务器可以提供的一个重要特性。
1.1.3 非阻塞型I/O及事件环机制
为了实现高性能,Node.js中采用了以下两种机制:
·非阻塞型I/O
·事件环
JavaScript脚本语言的一个特征是它只支持单线程。V8JavaScript脚本语言也是如此,因此不需要担心它会造成死锁现象。但是与客户端脚本语言不同的是,Node.js中为V8JavaScript脚本语言提供了非阻塞型I/O机制。例如,当在访问数据库取得搜索结果的时候,在开始访问数据库之后、数据库返回结果之前,存在一段等待时间。在传统的单线程处理机制中,在执行了访问数据库的代码之后,整个线程都将暂停下来,等待数据库返回查询结果之后才能继续执行其后面的代码。也就是说,I/O操作阻塞了代码的执行,极大地降低了程序的执行效率。由于Node.js中采用了非阻塞型I/O机制,因此在执行了访问数据库的代码之后将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中执行,从而提高了程序的执行效率。
另外,在Node.js中,虽然不具有因为用户鼠标单击按钮或输入文字等操作而触发的事件,但是具有由于客户端请求建立连接、通过此连接而接收客户端提交数据、停止客户端提交数据的接收等行为而触发的事件。在Node.js中,在一个时刻只能执行一个事件回调函数,但是在执行一个事件回调函数的中途可以转而处理其他事件(包括触发新的事件、声明该事件的回调函数等),然后返回继续执行原事件回调函数,这种处理机制称为事件环机制。
1.1.4 Node.js适合开发的应用程序
到目前为止,我们对Node.js进行了相关的概要介绍,那么,Node.js适合用来开发何种应用程序呢?回答是:当应用程序需要处理大量并发的输入/输出,而在向客户端发出响应之前,应用程序内部并不需要进行非常复杂的处理的时候,我们应该考虑使用Node.js来进行该应用程序的开发。例如,我们可以开发如下应用程序:
·聊天服务器:在一个具有很高人气的聊天应用程序中,在同一时刻通常可能存在着大量用户与聊天服务器之间的并发连接,而服务器端本身并不存在非常复杂的处理。
·综合服务类网站或电子商务网站的服务器:在这类网站的服务器端,往往可能在每秒钟内接收到多达上千条数据并且需要将这些数据书写到数据库中,Node.js是解决这类问题的关键。Node.js将通过其队列机制将这些数据迅速书写在缓存区中,然后再通过每一个单独的处理从缓存区中取出这些数据并将其书写到数据库中。如果使用其他服务器(如Apache服务器或Tomcat服务器)的话,由于这些服务器采用的均为阻塞型I/O机制,因此需要为每条数据(到数据库中)的写入等待一段时间。如果使用Node.js服务器,由于其采用的是非阻塞型I/O机制,因此可以同时实现这些数据到数据库中的写入,而不必再为每条数据的写入等待一段时间。