您的位置:首页 > Web前端 > Node.js

nodejs 设计思想杂记一 reactor模式

2016-07-05 22:12 471 查看
开始正题,reactor 模式nodejs关于异步的本质,以及隐藏在此模式背后的故事。如单进程单线程的架构、非阻塞IO。最后看下整个nodejs平台。

IO很慢,相比于CPU的处理速度来说,在非密集型计算的应用场景下,IO是一个拖慢速度的瓶颈。当然,现在正火的深度学习可以一次跑上几个月。。。。这种计算密集型的应用场景下除外。

一个传统的阻塞型io的例子,



线程池中每个线程处理一个链接,上下文切换,读写等待。。。。。性能空闲了很多。

非阻塞IO

立即返回而不是等待数据读写完毕,如果数据读写出错则返回一个预定义的常量。类似于c语言中回调函数。

实现非阻塞IO的方法一:busy-waiting+polling loop

resources = [socketA, socketB, pipeA];

while(!resources.isEmpty()) {

for(i = 0; i < resources.length; i++) {

resource = resources[i];

//try to read

var data = resource.read();

if(data === NO_DATA_AVAILABLE)

//there is no data to read at the moment

continue;

if(data === RESOURCE_CLOSED)

//the resource was closed, remove it from the list

resources.remove(i);

else

//some data was received, process it

consumeData(data);

}

}

实现起来很简单,缺点也很明显,cpu占用率过高,轮询的方式代价很大,但是也简单的说明的一个异步io的实现方式。

实现非阻塞IO的方法二:event notify/event loop

socketA, pipeB;

watchedList.add(socketA, FOR_READ); //[1]

watchedList.add(pipeB, FOR_READ);

while(events = demultiplexer.watch(watchedList)) { //[2]

//event loop

foreach(event in events) { //[3]

//This read will never block and will always return data

data = event.resource.read();

if(data === RESOURCE_CLOSED)

//the resource was closed, remove it from the watched list

demultiplexer.unwatch(event.resource);

else

//some actual data was received, process it

consumeData(data);

}

}

这种方式利用率高多了,如图



reactor 模式

终于开始正题了。。

nodejs以每一个 模块都很小 ,每个模块都work的很好的思想,并把这种思想作到了极致。

使用npm作为模块的管理,把可重用性以及可维护性做到极致。解决了dependancy hell。

一个小的模块还有如下优点:

容易理解与使用、测试与维护更加简便、更加容易传播。

每个人都可以传播自己的代码,省去的重复造轮子的工作。相比于cpp。。。。轮子轮子再造个轮子。

额。。。回来重新说reactor模式

其实reactor模式在上面已经说过了,上面的event notify,也叫event loop的一种特例。

看图说话



1。 发个req,然后就返回去执行下一条指令了

2。 event Demultiplexer  等待一组IO操作完成后。。。也就是等event queue把手头的活做完,把req加入event队列

3.    event queue 把所有的event一股脑丢尽event loop,执行去吧

4     执行完的任务返回给application,通过handle一一对应。

5a  还有要做的事情啊,啊?这么急?先给你做好了

5b 做完啦,结果给你吧

6    没有事情可以做,我先休息一会,event loop休息去了,有活再叫我

reactor模式到底是个啥?

有处于观察期的资源可用时,这时把资源和操作对应成event,把event分发给各自相关handle。

nodejs用的非阻塞io引擎:libuv

libuv兼容了win,*nix,mac的底层异步读写操作。c语言实现的跨平台的library。

libuv实现了reactor模式,提供api来创建event loop,管理event queue,运行异步io操作,对其他类型的任务queue。

之前说过要show整个nodejs的平台,还需要几个东西。。。。。

首先libuv,v8,然后就是javascript。

看图说话



欢迎加q群243153894交流
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  nodejs node 设计模式