本文参考Doug Lea的Scalable IO in Java.

网络服务

随着网络服务的越来越多,我们对网络服务的性能有了更高的要求,提供一个高性能,稳定的web服务是一件很麻烦的事情,所以有了netty框架帮我们完成。

我们对各种各样的网络服务进行抽象,得到最基本的业务流程:

1:读取请求信息

2:对请求信息进行解码

3:进行相关的业务处理

4:对处理结果进行编码

5:发送请求

看到这,netty的ChannelHandler就是干这几件事情的。

传统的网络服务

在jdk1.4之前,我们只有BIO,所以当时的网络服务的架构是这样的。

每个线程处理一个请求, 由于线程个数和cpu个数的原因,这种设计性能是有上限的,所以就有了集群模式:tomcat集群。

/*** Created by gaoxing on 2015-01-20 .*/
public class ClasssicServer {public static void main(String[] args) {try {ServerSocket serverSocket=new ServerSocket(8888,10);System.out.println("server is start");while( ! Thread.interrupted()){new Thread(new Handler(serverSocket.accept())).start();}} catch (IOException e) {e.printStackTrace();}}static class Handler implements  Runnable{final Socket socket;final static int MAX_SIZE=1024;public Handler(Socket socket){this.socket=socket;}@Overridepublic void run() {//TODO//在这里对socket中的数据进行读取和处理,然后把结果写入到socket中去
        }}
}

高性能的IO目标和Reactor

1:高负载下可以稳定的工作

2:提高资源的利用率

3:低延迟

这有就有了分而治之和事件驱动的思想。这样没有thread就不用瞎跑了,cpu就不用不停的切换Thread . 这样提出了Reactor模式

1:Reactor接收IO事件发送给该事件的处理器处理

2:处理器的操作是非阻塞的。

3:管理事件和处理器的绑定。

这是一个单线程版本,所有的请求都是一个线程处理,当然Reactor不是无缘无故的提出来的,因为jdk提供了nio包,nio使得Reator得于实现

1:channels: 通道就是数据源的抽象,通过它可以无阻塞的读取数据

2:buffers  : 用来装载数据的,可以把从channel读取到buffer中,或者把buffer中的数据写入到channel中

3:selector : 用来监听 有IO事件,并告诉channel

4:selectionkeys:  IO事件和处理器绑定

/*** Created by gaoxing on 2015-01-20 .*/
public class Reactor implements Runnable {final Selector selector ;final ServerSocketChannel serverSocketChannel;public Reactor(int port) throws IOException {this.selector=Selector.open();this.serverSocketChannel=ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(port));//一定是非阻塞的,阻塞的一个通道就只能处理一个请求了serverSocketChannel.configureBlocking(false);//把OP_ACCEPT事件和Acceptor绑定SelectionKey sk=serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);sk.attach(new Acceptor());}@Overridepublic void run() {while(!Thread.interrupted()){try {selector.select();//该方法是阻塞的,只有IO事件来了才向下执行Set<SelectionKey> selected=selector.selectedKeys();Iterator<SelectionKey> it=selected.iterator();while(it.hasNext()){dispatch(it.next());}          selected.clear()          } catch (IOException e) {e.printStackTrace();}}}private void dispatch(SelectionKey next) {Runnable runnable= (Runnable) next.attachment();if(runnable!=null){runnable.run();}}private class Acceptor implements Runnable{@Overridepublic void run() {SocketChannel channel= null;try {channel = serverSocketChannel.accept();if (channel!=null){new Handler(selector,channel);}} catch (IOException e) {e.printStackTrace();}}}
}class Handler implements  Runnable
{final SelectionKey sk;final SocketChannel channel;final static int MAXSIZE=1024;ByteBuffer input=ByteBuffer.allocate(MAXSIZE);ByteBuffer output=ByteBuffer.allocate(MAXSIZE);static final int READING=0,SENDING=1;int state=READING;public Handler(Selector selector,SocketChannel channel) throws IOException {this.channel=channel;this.channel.configureBlocking(false);/*** 这个有个问题,ppt上register是0,*/sk=this.channel.register(selector,SelectionKey.OP_READ);sk.attach(this);/*** 这里的作用是,设置key的状态为可读,然后让后selector的selector返回。* 然后就可以处理OP_READ事件了*/sk.interestOps(SelectionKey.OP_READ);selector.wakeup();}@Overridepublic void run() {if (state==READING) read();if (state==SENDING) write();}void read(){state=SENDING;sk.interestOps(SelectionKey.OP_WRITE);}void write(){sk.cancel();}
}

上面代码注解理解有误:

sk=this.channel.register(selector,0);  这里是初始化一个SelectionKey 不监听事件
sk.interestOps(SelectionKey.OP_READ); 这里设置监听的事件为OP_READ

多线程的Reactor模式

现在的CPU多核的,为了提高对硬件的使用效率需要考虑使用多线程的Reactor设计模式,Reactor主要用来处罚事件的,但是事件的处理会降低Reactor的性能,考虑把事件的处理放到别的线程上来做,有点想android的设计模式,UI线程用来接收用户的事件,事件的处理放到线程去做来提高用户的体验。多线程Reactor有两种一种是Reactor线程只关注io事件,事件处理放到别的线程,一种对事件分类主Reactor只关注Accept事件,子Reactor关注read和write事件。事件处理放到线程去做,这也是netty的设计模式。

class HandlerPool implements  Runnable
{final SelectionKey sk;final SocketChannel channel;final static int MAXSIZE=1024;ByteBuffer input=ByteBuffer.allocate(MAXSIZE);ByteBuffer output=ByteBuffer.allocate(MAXSIZE);static ExecutorService executor = Executors.newFixedThreadPool(100);static final int READING=0,SENDING=1;int state=READING;public HandlerPool(Selector selector,SocketChannel channel) throws IOException {this.channel=channel;this.channel.configureBlocking(false);/*** 这个有个问题,这里注册的SelectionKey是不处理的,应该他监听的事件为0*/sk=this.channel.register(selector,0);sk.attach(this);/*** 这里的作用是,SelectionKey的监听事件为OP_READ。interestOps对哪个事件感兴趣*/sk.interestOps(SelectionKey.OP_READ);selector.wakeup();}@Overridepublic void run() {executor.execute(new Processer());}class Processer implements Runnable{@Overridepublic void run() {}}
}

这个就在Acceptor里面多实例化几个Selector,它处理Read和Write事件。

大致架构弄懂了。后面边看netty源码,边学习nio

转载于:https://www.cnblogs.com/gaoxing/p/4237789.html

NIO和Reactor相关推荐

  1. Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式

    本文介绍了Java中的四种I/O模型,同步阻塞,同步非阻塞,多路复用,异步阻塞.同时将NIO和BIO进行了对比,并详细分析了基于NIO的Reactor模式,包括经典单线程模型以及多线程模式和多Reac ...

  2. java NIO和Reactor模式

    Reactor模式和NIO 板桥里人 jdon.com 2002/11/08 本文可看成是对Doug Lea Scalable IO in Java一文的翻译. 当前分布式计算 Web Service ...

  3. NIO 主从Reactor服务

    NIO 主从Reactor服务 模型如下: 方案说明: Reactor主线程 MainReactor 对象通过select 监听连接事件, 收到事件后,通过Acceptor 处理连接事件 当 Acce ...

  4. Java I/O模型从BIO到NIO和Reactor模式

    本文转发自技术世界,原文链接 http://www.jasongj.com/java/nio_reactor/ 一.Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个 ...

  5. Java进阶知识点5:服务端高并发的基石 - NIO与Reactor模式以及AIO与Proactor模式

    一.背景 要提升服务器的并发处理能力,通常有两大方向的思路. 1.系统架构层面.比如负载均衡.多级缓存.单元化部署等等. 2.单节点优化层面.比如修复代码级别的性能Bug.JVM参数调优.IO优化等等 ...

  6. Reactor模式和NIO

    当前分布式计算 Web Services盛行天下,这些网络服务的底层都离不开对socket的操作.他们都有一个共同的结构: 1. Read request 2. Decode request 3. P ...

  7. IO模型有哪些,讲讲你理解的nio ,他和bio,aio的区别是啥,谈谈reactor模型。

    1.什么是BIO,NIO,AIO JAVA BIO:同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程并处理,如果这个连接不做任何事情会造成不必要的开销,当然 ...

  8. Nio得知3——该示范基地:多路复用器模式

    Reactor模式和NIO 本文可以看作是Doug Lea Scalable IO in Java一文的翻译. 当前分布式计算 Web Services盛行天下,这些网络服务的底层都离不开对socke ...

  9. 关于BIO | NIO | AIO的讨论

    关于BIO | NIO | AIO的讨论一直存在,有时候也很容易让人混淆,就我的理解,给出一个解释: BIO | NIO | AIO,本身的描述都是在Java语言的基础上的.而描述IO,我们需要从两个 ...

最新文章

  1. [转载]ICollectionView让MVVM更简单
  2. 数据中心余热回收再思考
  3. 数据库-优化-MYSQL的执行顺序
  4. 依赖于boodtrap3的插件推荐以及bootrap发展前景
  5. apache+php+mysql服务器搭建
  6. 在网页中加入神奇的效果
  7. C++是C语言演变过来的,为何不能代替C语言?
  8. 我的女儿二三事(七)(r12笔记第58天)
  9. soapui调用java类_soapui接口测试-验签值处理-调用java的加密jar包
  10. 计算机函数求销售额公式,excel用函数求出销售额 使用TREND函数来对销售额进行预测的方法...
  11. 北斗心脏——高精度时间频率系统
  12. 思科网络工程师面试题
  13. BOOST的JSON解析库Boost.JSON简介
  14. C语言复习 随手写3
  15. 水溶性CdseTe ZnS量子点
  16. 【小5聊】代码管理工具之git等代码账号使用凭据管理器查看windows凭据
  17. C++实现RS485通信
  18. 关于汇编语言中的立即寻址和直接寻址
  19. angularjs与jquery特效slidetoggle结合
  20. 提高IT项目沟通技巧

热门文章

  1. 关于2016年房价的思考
  2. mobx使用数组提示越界_向Mobx可观察数组添加操作
  3. lsm tree java_LSM-tree 基本原理及应用
  4. Java开发主流框架是什么?
  5. echarts雷达图线的样式_echarts 雷达图的个性化设置
  6. 机器人 陆梅东_上海乐高创客工作坊活动顺利举行
  7. python中文字符_python处理中文字符
  8. 使用python下载文件_详解使用Python下载文件的几种方法
  9. 标杆徐linux云计算视频,标杆徐2018 Linux自动化运维系列④: Shell脚本自动化编程实战...
  10. birt预览能有内容发布后没内容_谷歌突然推出Android 11开发者预览版 新版带来部分新功能和改进...