上次讲到事件驱动模式,今天我们来好好分析下netty的事件模式的几个类型。

先从NIO讲起,

JAVA NIO方面Selector给Reactor模式提供了基础,Netty结合Selector和Reactor模式设计了高效的线程模型。

这里有个题外话,reactor英文的含义是什么?我们可以稍微了解下:

美[ri'æktər]英[ri'æktə(r)]
  • n.核反应堆
  • 网络反应器;电抗器;反应者

中文翻译是反应者,在我们这个语境,翻译成反应者或响应者,都是正解。就把它想象成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

最新文章

  1. redis 集群创建常见几个问题
  2. Java-类与类之间的关系
  3. sscanf函数
  4. WindowsPhone-GameBoy模拟器开发五--使用XNA初略实现Gameboy显示系统
  5. UI5_UIAlertView与UIActionSheet
  6. ASP.NET MVC 学习6、学习使用Code First Migrations功能,把Model的更新同步到DB中
  7. Protobuf, understand the hood
  8. 滑动冲突的补充——Event的流程走向
  9. C#中 Thread,Task,Async/Await,IAsyncResult 的那些事儿!
  10. vue学习笔记 实例(二)
  11. 从源码角度简单看StringBuilder和StringBuffer的异同
  12. python操作mysql,增,删,改,查
  13. mysql5.0手动升级8.0.15,并链接到navicat
  14. MATLAB System Generator初识
  15. Selenium Webdriver概述(转)
  16. 【Oracle】Oracle的内外连接
  17. HDU 1074 Doing Homework (dp+状态压缩)
  18. 关于错误errno EFAULT:Bad address
  19. 深入理解java集合框架之---------Arraylist集合 -----构造函数
  20. C++中虚函数和纯虚函数的区别与总结

热门文章

  1. React事件方法、React定义方法的几种方式、获取数据、改变数据、执行方法传值
  2. flutter 屏幕宽高 状态栏高度
  3. idea 编译 netty 源码
  4. The window object
  5. JS对象—数组总结(创建、属性、方法)
  6. HtML5与CSS3基础
  7. Linux字符界面字符颜色显示
  8. 拉格朗日乘法与KKT条件
  9. ubuntu/work
  10. Windows2012r2 安装SQLSERVER2017 与 SQLSERVER2016 的错误提示解决KB2919355 以及 KB2919442