nodejs的机制是单线程,这个线程里面,有一个事件循环机制,处理所有的请求。如图所示。在事件处理过程中,它会智能地将一些涉及到IO、网络通信等耗时比较长的操作,交由worker threads去执行,执行完了再回调,这就是所谓的异步IO非阻塞吧。但是,那些非IO操作,只用CPU计算的操作,它就自己扛了,比如算什么斐波那契数列之类。它是单线程,这些自己扛的任务要一个接着一个地完成,前面那个没完成,后面的只能干等。因此,对CPU要求比较高的CPU密集型任务多的话,就有可能会造成号称高性能,适合高并发的node.js服务器反应缓慢。
图解NodeJS【基于事件、回调的单线程高性能服务器】原理
轮询技术的缺点在于应用程序要主动调用,会造成占用较多CPU时间片,性能较为低下。
理想的异步I/O应该是应用程序发起异步调用,而不需要进行轮询,进而处理下一个任务,只需在I/O完成后通过信号或是回调将数据传递给应用程序即可。
Node只是表面暴露给用户的javascript代码是单线程的,底层还是多线程的。
Node.js选择的异步I/O方案:由于Windows平台和*nix平台的差异,Node.js提供了libuv来作为抽象封装层,使得所有平台兼容性的判断都由这一层次来完成,保证上层的Node.js与下层的libeio/libev及IOCP之间各自独立。Node.js在编译期间会判断平台条件,选择性编译unix目录或是win目录下的源文件到目标程序中。
每次循环中,它会调用IOCP相关的GetQueuedCompletionStatus方法检查是否线程池中有执行完的请求,如果存在,poll操作会将请求对象加入到loop的pending_reqs_tail属性上。 另一边这个循环也会不断检查loop对象上的pending_reqs_tail引用,如果有可用的请求对象,就取出请求对象的result属性作为结果传递给oncomplete_sym执行,以此达到调用JavaScript中传入的回调函数的目的。 至此,整个异步I/O的流程完成结束。其流程如下:
初探Node.js的异步I/O实现
使用Node的时候,会在javascript触发一些命令调用方法,这些方法会被包装成一个对象,放入线程池,然后前面的方法就返回了,继续执行下面的JS代码。
线程池中采用多线程的方式执行,执行完的对象放入事件循环队列。
事件循环队列采用类似while(true)这种循环的方式,不断的查看是否有事件,并且读取是否包含回调,由于前面回调函数被包装到对象中,这里直接调用执行就可以了。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
- http://nodejs.org/ 官方网站,最简单的示例,详尽的文档(中文版http://cnodejs.org/cman/)
- github上的https://github.com/joyent/node以及各种周边库
- The Node Beginner Book the node beginner book,深入浅出,做完很有成就感
- 简单的NodeJs MVC http://cnodejs.org/blog/?p=342,出自CNODEJS中文社区,上面的其他文章多订阅多看看
- Google和订阅,Google各种东西教程资料,好的blog就订阅下,不断学习,比如说http://howtonode.org/
- npm:NodeJs包管理器
- express:服务器端比较流行的MVC框架,处理服务请求,路由转发,逻辑处理
- mongoose:mongodb包装,更方便使用数据库
- http://socket.io:实现服务端和客户端socket通信解决方案
- backbone:客户端MVC框架,编写客户端应用(豆瓣说)
- coffeescript:提高JavaScript的可读性,健壮性
- zombie:浏览器子集,编写html解析器,轻形javascript客户端测试
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1、进入 http://nodejs.org 下载开发环境
http://Expressjs.com 下载安装Express npm install -g express
继续安装ejs:npm install ejs
如果要想运行Node.js程序,则现在只能够使用“node app.js”,而这样的运行方式,如果在app.js文件修改之后往往需要重新启动才可以加载新的内容,这对于开发是非常不方便的, 为此,可以使用一个supervisor组件包,它可以动态的加载修改之后的开发程序。
下载安装supervisor
npm install -g supervisor
利用supervisor方式运行程序
supervisor app.js
6、模块:Node.js提供了exports和require两个对象,其中exports是模块公开的接口,require用于从外部获取一个模块的接口,即获取模块的exports对象。exports本身仅仅是一个普通的空对象,即{},它是专门用来声明接口
7、包是在模块基础上更深一步的抽象,Node.js的包类似于C/C++的函数库或者java的类库,它讲某个独立的功能封装起来,用于发布、更新、依赖管理的版本控制。npm解决包的发布和获取需求。
d.包的发布
8、调试代码