第一章 Node简介 1.1 Node的诞生历程 Node的创始人是Ryan Dahl,后来他将自己掌门人的身份交给了Isaac Z. Schlueter;后者是Node的包管理器Npm的作者,之后N
第一章 Node简介
1.1 Node的诞生历程
Node的创始人是Ryan Dahl,后来他将自己掌门人的身份交给了Isaac Z. Schlueter;后者是Node的包管理器Npm的作者,之后Node版本的发布和修复bug的工作,均由他来接手。
1.2 Node的命运与起源
Node有许多别称,包括NodeJS,Nodejs,Node.js。
- 为什么是JavaScript
Ryan Dahl 是一名资深C/C++程序员,他发现高性能的web服务器需要满足事件驱动和非阻塞I/O这两个特点;Ryan 最初的目的是创建一个高性能服务器,评估C、lua等语言,他认为C语言的门槛太高,lua语言的历史负担比较重(lua有很多阻塞的I/O库,即使为它增加非阻塞的I/O库,使用者也较难改变习惯去使用)。适逢第二次浏览器大战,chrome的javascrpt浏览器引擎V8胜出;Ryan认为,javascript在浏览器端的应用基于事件驱动,且在后端还没有市场,因此也没有历史包袱,于是选择了它。
- 为什么叫Node
项目的发展远远超过了Ryan最初单纯想构建一个web服务器的想法,成为了一个网络应用的基础框架;其中每一个进程都相当于网络的结点,因此,这个项目取名叫Node(Ryan最初是想叫它web.js的)。
1.3 Node给JavaScript带来的意义
Chrome浏览器和Node的组件构成如图。在Chrome中,JavaScript被限制在浏览器中使用,使用范围取决于浏览器提供的API;根据HTML提供的API,JavaScript只能和CSS、DOM树打交道。
而Node的实现与Chrome相似,都是基于事件的异步架构,在这里Node可以编写服务器、操作数据库、如Web Workers一样玩转多进程。
1.4 Node的特点
Node作为JavaScript的运行平台,它保留了JavaScript的所有接口,没有改写语言本身的特性。
- 异步I/O
Ryan Dahl排除万难,在底层构建了许多异步的API,从文件读取到网络请求。以文件读取为例,下图是一个异步调用的图解:
当发起读取文件的操作后,调用者不必等待事件的执行,而是可以进行其他的操作;当Node处理完请求后,会通知调用者,调用者再执行回调函数。可以看出,Node与前端的Ajax调用类似,都是符合“Don’t call me ,I will call you.”
- 事件与回调函数
Node通过事件来执行相应的业务逻辑,通过回调函数来实现异步操作;但是这种代码的编写逻辑与执行顺序无关的方式,也增加了对业务划分、事件的提炼等流程控制方面的复杂度。
- 单线程
Node保持了JavaScript在浏览器中的单线程的特点,好处是,不用像多线程编程那样处处在意状态同步的问题,也没有死锁状态的存在,也没有上下文交换带来的性能上的开销。
但是单线程也有以下方面的弱点:
无法利用多核CPU;
健壮性不好,错误会引起整个应用程序退出;
大量计算占用CPU导致无法继续调用异步I/O。
Node采用了与HTML5中的web workers相同的思路来解决单线程的问题:child_process。通过将计算任务分发到子进程来分解大量计算,并通过进程间的通信来传递消息。
- 跨平台
Node从0.6.0版本开始,通过在操作系统上构建了一层平台级架构libuv来兼容windows和*nix操作系统。
1.5Node的应用场景
- I/O密集型
I/O密集型场景给单线程应用带来的问题是I/O阻塞,Node通过I/O异步调用机制能够很好的应对。
- 是否不擅长CPU密集型任务
CPU密集型场景给单线程应用带来的挑战是,由于计算长时间的占用CPU,导致CPU时间片不能释放,使后续I/O操作无法发起;可以通过适当分解计算任务来缓解这个问题。
但是如果:
CPU造成的影响(CPU密集型任务) > I/O阻塞造成的影响(I/O密集型)
那么需要重新评估应用场景---这可能就是一个纯计算的场景。这种情况下,可以通过以下两种方式来应对:
1) 编写扩展C/C++程序来进行计算
2) 将一部分子进程常驻Node来进行计算,通过消息传递给主线程。
(图)
- 与遗留系统和平共处
过去在web端,通常采用同步的方式来编写程序,这种串行传递数据的方式造成了大量串行等待的时间;如果用多线程来解决,又显得小题大做;Node在语言层面天然可并行的特点能够很好的解决这个问题,但这并非意味着我们需要抛弃原来的系统,遗留系统仍然可以作为后端和接口继续使用。
- 分布式应用
对于大量数据的查询,可能需要对数据库集群做划分和映射,对于单张表仍然是普通的SQL操作,但中间层实际是并行的去多个数据库查询。对数据库而言,这是一个复杂的操作,对Node而言,这只是一次简单的I/O操作。
1.6Node的使用者
- Node的应用和使用代表主要有以下几类:
- 前后端编程环境统一,减少上下文交换带来的损耗:雅虎的YUI3
- 高性能I/O用于实时应用:花瓣网,蘑菇街的实时消息推送
- 并行I/O用于分布式应用:阿里巴巴、eBay
- 云计算平台提供Node支持:微软的Axure
- 游戏开发领域对实时和并发的高要求:网易
- 工具类应用