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交流
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交流
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- 使用ruby部署工具mina快速部署nodejs应用教程
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解