服务端javascript

  服务端javascript?! 是的,你没有听错,我也没有写错。就是服务端javascript!以前也许我们曾用过或者听说过Google GWT API可以用java实现Web前端,却没有听说过javascript也可以告别浏览器,另谋高就!
  其实微软IIS早就有把javaScript包养的前科咯~ 今天我们不谈变态的微软,就来说说另一种支持后端javascript的技术-Node.js.
  Node.js是大牛Ryan Dahl实现的,它既是用来处理大规模并发网络请求的服务器;又是后端javascript开发工具包。众所周知,javascript是单线程,解释型 的语言。而web应用会面临大量的用户请求,因此快速响应尤为重要。一般web服务器都采用多线程并发编程。然后Node.js既然基于 javascript,它又怎样快速地处理大批量的用户请求呢?这是我看到Node.js首先想到的问题之一!

一、Node背景

  Node.js 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。当前的服务器程序有什么问题?我们来做个数学题。在 Java™ 和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 的配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户群的增长,如果希望您的 Web 应用程序支持更多用户,那么,您必须添加更多服务器。当然,这会增加服务器成本、流量成本和人工成本等成本。除这些成本上升外,还有一个潜在技术问题,即 用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。鉴于上述所有原因,整个 Web 应用程序架构(包括流量、处理器速度和内存速度)中的瓶颈是:服务器能够处理的并发连接的最大数量。

  Node.js 解决这个问题的方法是:更改连接到服务器的方式。每个连接发射一个在 Node 引擎的进程中运行的事件,而不是为每个连接生成一个新的 OS 线程(并为其分配一些配套内存)。 Node.js 声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞 I/O 调用。 Node.js 还宣称,运行它的服务器能支持数万个并发连接。

二、Node特性

  • 单进程单线程

   Node.js采用C++语言编写而成,是一个Javascript的运行环境。据Node.js创始人Ryan Dahl回忆,他最初希望采用Ruby来写Node.js,但是后来发现Ruby虚拟机的性能不能满足他的要求,后来他尝试采用C++ 嵌入 V8(v8本身采用c++开发,故Nodes.js使用C++ 主要是做v8扩展、绑定的一些依赖库 比如libev,libeio )引擎 。既然不是Javascript应用,为何叫.js呢?因为Node.js是一个Javascript 的运行环境。提到Javascript, 大家首先想到的是日常使用的浏览器,现代浏览器包含了各种组件,包括渲染引擎、Javascript引擎等,其中Javascript引擎负责解释执行网 页中的Javascript代码。提到javascript,web开发者都知道它是一门单线程,解释型的高级语言。它支持闭包,函数式编程,基于事件驱 动,采用回调机制,匿名函数 。。。Node.js延续了javascript风格,当然也采用单进程单线程模式运行。

  • 嵌入 Google Chrome浏览器的V8引擎

  V8引擎是google chrome浏览器的javascript解释器,用于解释并执行javascript代码。 google 使用 V8 创建了一个用 C++ 编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何 应用程序。V8 JavaScript 引擎并不仅限于在一个浏览器中运行。因此,Node使用 Google 编写的 V8 JavaScript 引擎,并将其重建为可在服务器上使用。

  • 非阻塞I/O操作

  如果你有多线程的编程经验,你一定了解多线程就会存在并发,并发就需要对共享资源进行同步控制。常规的IO操作,在多线程环境中,我们不得不进行阻塞(同 一时刻只能有一个线程进行IO操作)操作。然而Node却不按常规出牌,它就采用单线程模式,并且进行非阻塞IO操作。我就会想,既然它是单线程,它又说 进行的是非阻塞IO操作,这不是矛盾吗?因为稍微有点多线程编程经验的同志都知道要进行多非阻塞的话,那必须是异步执行的,如果异步执行的话,又不得不多 线程运行才能保证异步。那么Node标榜的单线程,非阻塞,异步执行又是怎么做到的呢?这是我想到的问题之二。

  • 基于事件驱动模型

  前面说到javascript是一门单线 程,解释型高级语言。它支持闭包,函数式编程,基于事件驱动,采用回调机制,匿名函数等特点。没错,Node就是借鉴了它的所有优点,基于事件驱动模型。 然而什么又是事件驱动模型呢?我们想想javascript事件模型是怎样的呢?javascript内置了系统事件,开发人员为组件注册事件,绑定事件 处理回调函数。当组件触发该事件时,系统会自动调用为组件绑定的事件处理函数。同样Node也采用事件驱动模型, 实际上,服务器端和客户端没有任何区别。没错,这没有按钮点击操作,也没有向文本字段键入的操作,但在一个更高的层面上,事件正在发生。一个连接被建立,这是一个事件!数据通过连接进行接收,这也是一个事件!数据通过连接停止,这还是一个事件!Node 采用了事件轮询(event loop)的架构,并使用一系列非阻塞库支持event loop,本质上就是为文件系统、数据库之类的资源提供接口。当你向文件系统发送一个请求时,无需等待硬盘(寻址并检索文件),硬盘准备好的时候非阻塞接 口会通知Node.简单的说,所有请求以及请求回调函数都将交给Node事件轮询线程,该线程负责在资源操作结束时,回调请求处理函数。需要注意的是资源 操作不在该线程中进行,它将由提供资源接口方处理,待处理完成后通知轮询线程请求已经完成,所以它不会阻塞后续请求,保证了单线程也能实现非阻塞异步请 求,当然处理大批量并发请求也不再是什么问题!(回答了我的疑问)。


最后引用百度百科Node.js中的一句话:

Node机制的根本原理是多利用CPU、高速缓存处理相应访问,减少比如像硬盘到内存,或到高速缓存中的检索读取的等待时间。

猜你喜欢

转载自andy0807.iteye.com/blog/1442815