《深入浅出nodejs》读书笔记
本书适合人群,在了解了node基本过程后,有好奇心想了解更多node知识。
第一章 Node简介
1.1 Node的诞生历程
1.2 Node的命名与起源
1.2.1 为什么是JavaScript
Web服务器的几个要点:事件驱动、非阻塞I/O。
Ryan Dahl考虑到高性能、符合事件驱动、没有历史包袱这3个主要原因,JavaScript成为了Node的实现语言。
1.2.2 为什么叫Node
每一个Node进程都构成网络应用中的一个点,这就是他名字所含意义的真谛。
1.3 Node给JavaScript带来的意义
V8给Chrome浏览器带来了一个强劲的心脏。
Node的结构与Chrome十分相似。他们都是基于时间驱动的异步架构,浏览器通过时间驱动来服务界面上的交互,Node通过事件驱动来服务I/O。
在Node中,JavaScript可以随心所欲地访问本地文件,可以搭建WebSocket服务器端,可以连接数据库,可以如Web Workers一样玩转进程。
Node打破了过去JavaScript只能在浏览器中运行的局面。
1.4 Node 的特点
作为后端JavaScript的运行平台,Node保留了前端浏览器JavaScript中那些熟悉的接口,没有改写语言本身的任何特征,依旧基于作用域和原型链,区别在于他将前端中广泛运用的思想迁移到了服务端。
1.4.1 异步I/O
我们只知道相应将在这个异步请求结束后执行,但并不知道具体的时间点。异步调用中对于结果值的捕获是符合:Don't call me, I will call you的原则的,这也是注重结果,不关心过程的一种表现。
$.post('/url', {title : '深入浅出Node.js'}, function (data){ console.log('收到响应'); }); console.log('发送Ajax结束');
如图,一个经典的Ajax调用:
在Node中,异步也很常见。
var fs = require('fs'); fs.readFile('/path', function(){ console.log('读取文件完成'); }); console.log('发起读取文件');
再看一下流程图:
在Node中,绝大多数的操作都是以异步方式进行调用的。每个调用之间无须等待之前的I/O调用结束。
对于异步I/O而言,耗时:MAX(T1,T2,T3...)
对于同步I/O而言,耗时:SAM(T1,T2,T3...)
1.4.2 事件于回调函数
Node将前端浏览器中应用广泛且成熟的事件引入后端,配合异步I/O,将事件点暴露给业务逻辑。
举例:
var http = require('http'); var querystring = require('querystring'); //侦听服务器request事件 http.createServer(function(req, res){ var postDate = ''; req.setEcoding('utf8'); //侦听请求的data事件 req.on('data', function(trunk){ postData = trunk; }); //侦听请求的end事件 req.on('end', function(){ res.end(postData); }); }).listen(3000); console.log('服务器启动完成');
无论前端还是后端,事件都是常用的。
像JavaScript一样,函数在Node中也是第一等公民,可以将函数作为对象传递给方法实参进行调用。
1.4.3 单线程
Node保持了JavaScript在浏览器中单线程的特点。
好处:不用像多线程编程那样处处在意状态的同步,这里没有死锁的存在,也没有线程上下文交换所带来的性能上的开销。
弱点:
a. 无法利用多核CPU
b. 错误会引起整个应用退出,应用的健壮性值得考验
c. 大量计算占用CPU导致无法继续调用I/O
Node采用了与Web Workers相同的思路来解决单线程中大计算量的问题:child_process
子进程的出现,意味着Node可以从容地应对单线程在健壮性和无法利用多核CPU方面的问题。
1.4.4 跨平台
1.5 Node的应用场景
1.5.1 I/O密集型
Node处理I/O的能力是值得竖起拇指称赞的。
I/O密集的优势主要在于Node利用事件循环的处理能力,而不是启动每一个线程为每一个请求服务,资源占用极少。
1.5.2 是否不擅长CPU密集型业务
V8的执行效率是毋庸置疑的。
这里举证:相同的裴波那契数列计算(n=40)。node性能还是不错的。
CPU密集型应用给Node带来的主要挑战是:由于JavaScript单线程的原因,如果长时间运行的计算,将会导致CPU时间片不能释放,使得后续I/O无法发起。但是适当调整和分解大型计算任务为多个小任务,使得运算能够适当释放,不阻塞I/O调用的发起,这样既可同时享受到并行异步I/O的好处,又能充分利用CPU。
Node虽然没有提供多线程用于计算支持,但是还是有一下两个方式充分利用CPU:
1. Node可以通过编写C/C++扩展方式更高效地利用CPU。
2. 可以通过子进程的方式,将一部分Node进程当做常驻服务器进程用于计算,然后利用进程间的消息来传递结果,将计算与I/O分离,这样还能充分利用CPU。
1.5.3 与遗留系统和平共处
国内的雪球财经是个很好的实践。
1.5.4 分布式应用
阿里巴巴的数据库平台对Node的分布式应用算是一个典型的例子。
1.5.6 Node的使用者
1. 前后端变成语言环境统一。
2. Node带来的高性能I/O用于实时应用。
3. 并行I/O使得使用者可以更高效地利用分布式环境。
4. 并行I/O,有效利用稳定接口提升Web渲染能力。
5. 云计算平台提供Node支持。
6. 游戏开发领域。
7. 工具类应用。
第二章 模块机制链接地址: