I/O模型系列之三:IO通讯模型BIO NIO AIO

1、传统的BIO

网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通讯,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端经过链接操做向服务端监听的地址发起链接请求,经过三次握手创建链接,若是链接创建成功,双方就能够经过网络套接字(Socket)进行通讯。html

在基于传统同步阻塞模型开发中,ServerSocket负责绑定IP地址,启动监听端口,Socket负责发起链接操做,链接成功以后,双方经过输入和输出流进行同步阻塞式通讯。java

BIO通讯模型图编程

    BIO的服务端通讯模型:采用BIO通讯模型的服务端,一般由一个独立的Acceptor线程负责监听客户端的链接,它接收到客户端链接请求以后为每一个客户端建立一个新的线程进行链路处理,处理完成以后,经过输出流返回应答给客户端,线程销毁。这就是典型的一请求一应答通讯模型。  segmentfault

  

  该模型最大的问题就是缺少弹性伸缩能力,当客户端并发访问量增长后,服务端的线程个数和客户端并发访问数呈1:1的正比关系,因为线程是JAVA虚拟机很是宝贵的系统资源,当线程数膨胀以后,系统的性能将急剧降低,随着并发访问量的继续增大,系统会发生线程堆栈溢出、建立新线程失败等问题,并最终致使进程宕机或者僵死,不能对外提供服务。后端

它的弊端有不少:服务器

1.性能问题:一链接一线程模型致使服务端的并发接入数和系统吞吐量受到极大限制;网络

2.可靠性问题:因为I/O操做采用同步阻塞模式,当网络拥塞或者通讯对端处理缓慢会致使I/O线程被挂住,阻塞时间没法预测;多线程

3.可维护性问题:I/O线程数没法有效控制、资源没法有效共享(多线程并发问题),系统可维护性差;并发

2、伪异步IO编程

为了解决同步阻塞IO面临的一个链路须要一个线程处理的问题,后来有人对它的线程模型进行了优化,后端经过一个线程池来处理多个客户端的请求接入,造成客户端个数M:线程池最大线程数N的比例关系,其中M能够远远大于N,经过线程池能够灵活的调配线程资源,设置线程的最大值,防止因为海量并发接入致使线程耗尽。 下面,咱们结合链接模型图和源码,对伪异步IO进行分析,看它是否可以解决同步阻塞IO面临的问题。框架

伪异步IO模型图

采用线程池和任务队列能够实现一种叫作伪异步的IO通讯框架,它的模型图以下:

 

  当有新的客户端接入的时候,将客户端的Socket封装成一个Task(该任务实现java.lang.Runnable接口)投递到后端的线程池中进行处理,JDK的线程池维护一个消息队列和N个活跃线程对消息队列中的任务进行处理。因为线程池能够设置消息队列的大小和最大线程数,所以,它的资源占用是可控的,不管多少个客户端并发访问,都不会致使资源的耗尽和宕机。 

3、NIO(多路复用器Selector)

  Java NIO的实现关键是经过多路复用IO技术实现的,多路复用的核心就是经过Selector来轮询注册在其上的Channel,当发现某个或者多个Channel处于就绪状态后,从阻塞状态返回就绪的Channel的选择键集合,进行IO操做。

  全部的 IO 在NIO 中都从一个Channel 开始。Channel 有点象流。 数据能够从Channel读到Buffer中,也能够从Buffer 写到Channel中。

  screenshot.png

 

Selector容许单线程处理多个Channel。若是你的应用打开了多个链接(通道),但每一个链接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。

这是在一个单线程中使用一个Selector处理3个Channel的图示:

selector

4、AIO异步IO

   

5、几种IO模型对比

  screenshot.png

BIO | NIO | AIO 以Java的角度,理解以下:

    • BIO,同步阻塞式IO,简单理解:一个线程处理一个链接,发起和处理IO请求都是同步的
    • NIO,同步非阻塞IO,简单理解:一个线程处理多个链接,发起IO请求是非阻塞的但处理IO请求是同步的
    • AIO,异步非阻塞IO,简单理解:一个有效请求一个线程,发起和处理IO请求都是异步的

    1 BIO模型中经过SocketServerSocket完成套接字通道实现。阻塞,同步,链接耗时。
    2 NIO模型中经过SocketChannelServerSocketChannel完成套接字通道实现。非阻塞/阻塞,同步,避免TCP创建链接使用三次握手带来的开销。
    3 AIO模型中经过AsynchronousSocketChannelAsynchronousServerSocketChannel完成套接字通道实现。非阻塞,异步

    BIO 阻塞同步通讯模式,客户端和服务器链接须要三次握手,使用简单,但吞吐量小
    NIO 非阻塞同步通讯模式,客户端与服务器经过Channel链接,采用多路复用器轮询注册的Channel。提升吞吐量和可靠性。
    AIO 非阻塞异步通讯模式,NIO的升级版,采用异步通道实现异步通讯,其read和write方法均是异步方法。

6、抄录网址

BIO、NIO、AIO 区别和应用场景

java BIO/NIO/AIO 学习

Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)

Netty序章之BIO NIO AIO演变

相关文章
相关标签/搜索