java高并发实战Netty+协程(Fiber)|系列1(续)|事件驱动模式和零拷贝
上次讲到事件驱动模式,今天我们来好好分析下netty的事件模式的几个类型。
先从NIO讲起,
JAVA NIO方面Selector给Reactor模式提供了基础,Netty结合Selector和Reactor模式设计了高效的线程模型。
这里有个题外话,reactor英文的含义是什么?我们可以稍微了解下:
- n.核反应堆
- 网络反应器;电抗器;反应者
- 变形复数:reactors;
中文翻译是反应者,在我们这个语境,翻译成反应者或响应者,都是正解。就把它想象成KFC的前台服务员好,她就是一个响应者,也叫reactor.
现在我们来看下Reactor模式图:
如上图所示,所谓的reactor模式,就是我们上篇文章所说的,KFC前后服务员加后台服务员的模式。
前台服务员(同时代表上图的demultiplexer和dispatcher)只负责接待客户的点汉堡的请求和订单分派,做汉堡的活让后台台服务员(代表上图的handler)去做。
做好后,后台再通知前台,由前台转交给客户。
这个很好理解。
好,那我们现在来看看Java NIO的reactor的几个模式:单线程模式,多线程模式,主从模式。
先看单线程模式:
如上图所示,所谓单线程模式,只有一个线程(acceptor)去处理客户的请求,然后,这个线程还要做read,send等工作,相当于是个多面手。
就好像KFC前台后台都只有一个服务员。
这个模式,如果客户只有一个的话,是可以处理。但如果,是用餐高峰期,一下子来了十个客户,那就不好处理了。
怎么办?
很自然,我们可以增加后台服务员,并且因为后台的工作比较多,后台服务员可以多个。这就是多线程模式。
再看多线程模式图:
如上图所示,用线程池(多个服务员)去处理read,decode,compute,encode任务。
就好像,前台一个服务员只负责下订单,然后把订单信息分派给多个后台服务员,同时服务多个客户,速度和效率也明显好很多,客户也不用等待太久。
那如果,这个时间来了几十个客户,如果只有一个前台服务员,这时,也处理不过来,怎么办?
很自然,增加前台服务员的数量。当然我们也不需要增加太多(毕竟有人力成本),现在我们只增加一位好了。
两位服务员,一主一从,我们就叫主从模式。
我们来看主从模式图:
如上图,将Reactor分成两部分,mainReactor负责监听server socket,accept新连接;并将建立的socket分派给subReactor。subReactor负责多路分离已连接的socket,读写网络数据,对业务处理功能,其扔给worker线程池完成。通常,subReactor个数上可与CPU个数等同。
还是用KFC的例子来说明,其中mainReactor是服务员小黄,她只负责下订单。subReactor就是服务员小张,他呢,只服务根据订单信息分派给后台服务员,并负责把汉堡和饮料放在托盘递给客户。
以上就是reactor模式说明,希望你已经明白了!
说完了Reactor的三种模型,那么Netty是哪一种呢?其实Netty的线程模型是Reactor模型的变种,那就是去掉线程池的第三种形式的变种,这也是Netty NIO的默认模式。Netty中Reactor模式的参与者主要有下面一些组件:
Selector
EventLoopGroup/EventLoop
ChannelPipeline
Selector即为NIO中提供的SelectableChannel多路复用器,充当着demultiplexer的角色,就像专门下订单的前台服务员。
ChannelPipeline负责安排Handler的顺序及其执行。因为后台工作多且杂,需要一个后台管理员负责管理和编排后台服务员的工作。这个后台管理员就是ChannelPipeline。
EventLoop的目的是为Channel处理IO操作,一个EventLoop可以为多个Channel服务。EventLoop就是后台服务员,一个后台服务员可以同时做几份汉堡。
EventLoopGroup会包含多个EventLoop。EventLoopGroup就是后台服务员的班组,几个后台服务员一个班组,一个班组固定处理一个固定 的后台工作。
明天继续。
s
最新文章
- redis 集群创建常见几个问题
- Java-类与类之间的关系
- sscanf函数
- WindowsPhone-GameBoy模拟器开发五--使用XNA初略实现Gameboy显示系统
- UI5_UIAlertView与UIActionSheet
- ASP.NET MVC 学习6、学习使用Code First Migrations功能,把Model的更新同步到DB中
- Protobuf, understand the hood
- 滑动冲突的补充——Event的流程走向
- C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!
- vue学习笔记 实例(二)
- 从源码角度简单看StringBuilder和StringBuffer的异同
- python操作mysql,增,删,改,查
- mysql5.0手动升级8.0.15,并链接到navicat
- MATLAB System Generator初识
- Selenium Webdriver概述(转)
- 【Oracle】Oracle的内外连接
- HDU 1074 Doing Homework (dp+状态压缩)
- 关于错误errno EFAULT:Bad address
- 深入理解java集合框架之---------Arraylist集合 -----构造函数
- C++中虚函数和纯虚函数的区别与总结