Node 高性能异步I/O框架

1,什么是Node?

      首先介绍下什么是nodejavascript

          1,单线程前端

               node保持了javascript在浏览器中单线程的特色,Node中,Javascript与其他线程没法共享任何状态。java

               单线程好处:不用到处在乎状态的同步,没有死锁,也没有线程上下文切换带来的性能开销。node

               单线程坏处:没法利用多核cpu,错误会引发整个应用退出,应用的健壮性值得考验,大量计算占用CPU没法继续调用异步I/O。git

              (注意:针对这些单线程坏处,node都有解决方案,这里不谈)es6

          2,跨平台 (基于libuv)github

兼容Windows和*nix平台主要得益于Node在架构层的的改动,它在操做系统与Node与操做系统之间构建了一层平台层框架,即libuv。目前,libuv已是许多系统实现跨平台的基础组件。web

经过良好的架构,Node的第三方C++模块也能够借助libuv实现跨平台,目前,除了没有保持更新的C++模块外,大部分C++模块都能实现跨平台的兼容。apache

          3,模块机制

                Java有类文件,Python有import机制,Ruby有require,PHP有include和require。浏览器端Javascript是没有标准的模块机制的,只能经过<script>标签引入代码显得杂乱无章,npm

               语言自己没有组织和约束能力,开发者不得不经过命名空间等方式人为约束代码。-》AMD,CMD。

              CommonJS规范:但愿javascript可以在任何地方运行。

                 CommonJS的规范提出主要是为了弥补当前Javascript没有标准的缺陷,以达到像Python,Ruby和Java具有开发大型应用的基础能力,而不是停留在小脚本程序的阶段.NodeJS是这种规范的实现

                 CommonJS规范涵盖了模块,二进制,Buffer,字符集编码,I/O流,进程环境,文件系统,套接字,单元测试,Web服务网管接口,包管理等。

                  CommonJS有不少实现,其中不乏不少大名鼎鼎的项目,好比 说:Apache的CouchDBnode.js等。但这些项目大 部分只实现了CommonJS的部分规范。具体的项目和实现部分参见官方网站的说                        明:http://commonjs.org/impl/

                   

                    Node模块实现

 

 

 

 

          4,应用场景

                I/O密集型

               是否不擅长cpu密集型?

      

 

 

 

2, 异步的原理。        

            但凡这种「既是单线程又是异步」的语言有一个共同特色:它们是 event-driven 的。驱动它们的 event 来自一个异构的平台。

      异步调用(封装参数)-》线程池(iocp)-》事件循环(监听者-》执行回调函数)

        阻塞I/O与非阻塞I/O:操做系统内核对于I/O只有两种方式:阻塞与非阻塞。

               [注]:操做系统对计算机进行了抽象,将全部输入输出设备抽象为文件,内核在进行文件I/O操做时,经过文件描述符进行管理,而文件描述符相似于应用程序与系统内核

       之间的凭证。应用程序若是须要进行I/O调用,须要先打开文件描述符,而后根据文件描述符去实现文件的数据读写。此处阻塞/O与非阻塞I/O的区别在于阻塞I/O完成整个获取

       数据的过程,而非阻塞I/O则不带数据直接返回,要获取数据,还须要经过文件描述符再次读取。

             阻塞I/O的一个特色是必定要等待系统内核层面完成全部数据操做后,调用才结束。以读取磁盘文件为例:系统内核在完成磁盘寻道,读取数据,复制数据到内存中以后这个调

       用才结束。如图:

                      

            阻塞I/O形成了CPU等待,浪费了等待时间,CPU的处理能力不能获得充分利用。为了提升性能,内核提升了非阻塞I/O。非阻塞I/O跟阻塞I/O的区别为调用以后当即返回,如图:

           

             非阻塞I/O返回以后,CPU的时间片能够用来处理其余事务,此时性能提高是明显的。

            但非阻塞I/O也存在一些问题。因为完整的I/O没有完成,当即返回并非业务层指望的数据,而仅仅是打当前调用的状态,为了获取完整的数据,应用层序须要重复调用I/O操做来

           确认是否完成。这种重复的调用判断操做是否完成的技术叫作轮询。[注]:任意技术都并不是是完美的,阻塞I/O形成CPU等待浪费,非阻塞I/O带来的麻烦倒是须要轮询取确认是否

          彻底完成数据获取,他会让CPU处理状态判断,是对CPU的资源浪费。

          轮询技术是有演进的,以减小I/O状态判断的CPU损耗。从read->select->poll->epoll。具体状况这里不谈。

         理想的非阻塞异步I/O:咱们指望的完美的异步I/O应该是应用程序发起非阻塞调用,无需经过遍历或者事件唤醒灯方式轮询,能够直接处理下一个任务,只须要在I/O完成后经过信号

         或者回调函数讲数据传递给应用程序便可,以下图:

                 

        幸运的是,在Linux中存在这中方式,它提供一个异步的I/O方式(AIO)就是经过信号或回调来传递数据的。但不幸的是,只有Linux中有,而且AIO只支持内核I/O中的O_DIRECT方法

       读取,而且没法利用系统缓存。

      现实的异步I/O

              现实确定比理想要骨感一些,可是要达成异步I/O的目标,也并不是难事。前面咱们讲场景都限定在单线程的状态下,多线程的方式就是另外一番风景了。经过让部分线程进行阻塞I/O

      或者非阻塞I/O加轮询技术来完成数据获取,让一个线程进行计算,经过线程之间的同窗讲I/O获得数据进行传递,这就轻松实现了异步I/O(尽管是模拟的)。

           

                  

        [注]:这里的I/O不只仅只局限于磁盘读写*nix将计算机抽象了一番,磁盘文件,硬件,套接字等几乎全部计算机资源都被抽象成了文件,所以这里的描述的阻塞和非阻塞的状况

         一样适合套接字等。

         [注]:咱们虽然时常提到Node是单线程的,这里的单线程仅仅指的是Javascript执行在但造成中罢了。在Node中,不管是什么平台,内部完成的I/O任务都是另有线程池的。

 

 3,为何要用异步?

      

4,经常使用的异步库

       Deferred是前端解决异步操做的一种编程范式,后来出现的Promise规范更是让其普适性大大提升。不过Promise规范也存在分岐。如今最流行的是Promise/A+规范。

 4,1  Promise

      在这些Promise的实现类库中,主要对两种类型的类库进行介绍。一种是被称为 Polyfill 的类库,另外一种是即具备  Promises/A+兼容性 ,又增长了本身独特功能的类库。

  

  PolyFill

       只须要在浏览器中加载Polyfill类库,就能使用IE10等或者尚未提供对Promise支持的浏览器中使用Promise里规定的方法。也就是说若是加载了Polyfill类库,就能在还不支持Promise          的环境中,运行Promise。

     1,jakearchibald/es6-promise

       一个兼容 ES6 Promises 的Polyfill类库。 它基于 RSVP.js 这个兼容 Promises/A+ 的类库, 它只是 RSVP.js 的一个子集,只实现了Promises 规定的 API。

     2,yahoo/ypromise

      这是一个独立版本的 YUI 的 Promise Polyfill,具备和 ES6 Promises 的兼容性。 

    3,getify/native-promise-only

       以做为ES6 Promises的polyfill为目的的类库 它严格按照ES6 Promises的规范设计,没有添加在规范中没有定义的功能。 若是运行环境有原生的Promise支持的话,则优先使用原生的          Promise支持。一个兼容 ES6 Promises 的Polyfill类库。 它基于  RSVP.js 这个兼容 Promises/A+ 的类库, 它只是 RSVP.js 的一个子集,只实现了Promises 规定的 API。 
 

  Promise扩展类库

       1,kriskowal/q

       使用过Node.js的人可能会知道Q模块,Q实现了Promises和 Deferreds等规范,在Node.js中环境或浏览器环境中使用。

      2,then/promise

       一个Promise/A+简单实现模块,除实现then方法外,还扩展一些标准外的方法,在Node.js中环境或浏览器环境中使用。

      3,petkaantonov/bluebird

    bluebird类库除了兼容Promise规范以外,还对Promise对象进行了必定的扩展,如:取消promise对象的运行等。另外,还在运行效率上进行了必定的优化。bluebird也是一             个npm模块,能够在Node.js中环境或浏览器环境中使用。 

 

    其余
      Async.js是一个流程控制工具包,提供了直接而强大的异步功能。参考这里: http://blog.fens.me/nodejs-async/
 《深刻浅出node》做者朴灵写的EventProxy参考: https://github.com/JacksonTian/eventproxy   
    大名鼎鼎的 co正是TJ大神基于ES6的一些新特性开发的异步流程控制库,基于它所开发的 koa更是被视为将来主流的web框架。

   Wind.js   https://github.com/JeffreyZhao/wind   http://blog.fens.me/nodejs-async-windjs/

相关文章
相关标签/搜索