Applicable BIO, NIO, AIO introduction and application of scene analysis

IO way is usually divided into several, simultaneous obstruction of BIO, synchronous non-blocking NIO, asynchronous non-blocking AIO.

A synchronous blocking BIO

Before JDK1.4, we establish a network connection using BIO mode, you need to start a serverSocket on the server, and then start the client socket to communicate to the server, the server establishes a need for each request by default heap thread waits for the request, and the client sends a request, first consult if there is a thread corresponding server, if it will not have to wait or rejected the request, if any, the client thread waits for the end of the request before continuing execution.

Second, the synchronous non-blocking NIO

NIO itself is based on event-driven ideas to complete, it mainly want to solve the big problem of concurrent BIO, the use of synchronous I / O, network applications, if you want to simultaneously handle multiple client requests, or to the client At the same time, and multiple servers to communicate, you must use multiple threads to handle. That is, each client request is assigned to a thread to handle separately. While doing so can meet our requirements, but also brought another problem. Since each create a thread is assigned to a memory space for this thread, and the operating system itself has certain limitations on the total number of threads. If the client requests too much, because the server program may be overwhelmed and rejected the client's request, the server may thus even paralysis.

NIO based Reactor, when the socket has a socket stream read or write, the operating system notifies the corresponding reference program for processing, and then applied to the stream buffer to read or write operation system. That is, this time, is not a connection must correspond to a processing thread, but rather valid request, corresponds to a thread, when no data connection is not working threads to handle.

BIO and NIO a more important difference is that we use BIO, it tends to introduce multithreading, each connected to a separate thread; and NIO is single-threaded or use a small amount of threads, each connected to a common thread.

NIO most important place when a connection is created, need not correspond to a thread, the connection will be registered on the multiplexer, so all connections requires only one thread can get, when the multiple thread when the multiplexer to poll found that requests, a thread to process before opening the connection, i.e. a request for a thread mode.

在NIO的处理方式中,当一个请求来的时候,开启线程进行处理,可能会等待后端应用的资源(JDBC连接等),其实这个线程就被阻塞了,如果并发上来,还会有BIO一样的问题。

HTTP/1.1出现后,有了Http长连接,这样除了超时和指明特定关闭的http header外,这个链接是一直打开的状态的,这样在NIO处理中可以进一步的进化,在后端资源中可以实现资源池或者队列,当请求来的话,开启的线程把请求和请求数据传送给后端资源池或者队列里面就返回,并且在全局的地方保持住这个现场(哪个连接的哪个请求等),这样前面的线程还是可以去接受其他的请求,而后端的应用的处理只需要执行队列里面的就可以了,这样请求处理和后端应用是异步的.当后端处理完,到全局地方得到现场,产生响应,这个就实现了异步处理。

三、异步非阻塞AIO

与NIO不同,当进行读写操作时,只需直接调用API的read或write方法即可。这两种方法均为异步的,对于读操作而言,当有流可读取时,操作系统会将可读的流传入read方法的缓冲区,并通知应用程序;对于写操作而言,当操作系统将write方法传递的流写入完毕时,操作系统主动通知应用程序。即可以理解为, read/write方法都是异步的,完成后会主动调用回调函数。   在JDK1.7中,这部分内容成为AIO,

主要在java.nio.channels包下增加了下面四个异步通道:

  • AsynchronousSocketChannel
  • AsynchronousServerSocketChannel
  • AsynchronousFileChannel
  • AsynchronousDatagramChannel

其中的read/write方法,会返回一个带回调函数的对象,当执行完读取/写入操作后,直接调用回调函数。  

BIO是一个连接一个线程。

NIO是一个请求一个线程。

AIO是一个有效请求一个线程。

先来个例子理解一下概念,以银行取款为例: 

  • 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写);
  • 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS(银行卡和密码),OS需要支持异步IO操作API);
  • 阻塞 : ATM排队取款,你只能等待(使用阻塞IO时,Java调用会一直阻塞到读写完成才返回);
  • 非阻塞 : 柜台取款,取个号,然后坐在椅子上做其它事,等号广播会通知你办理,没到号你就不能去,你可以不断问大堂经理排到了没有,大堂经理如果说还没到你就不能去(使用非阻塞IO时,如果不能读写Java调用会马上返回,当IO事件分发器会通知可读写时再继续进行读写,不断循环直到读写完成)

四、java对BIO、NIO、AIO的支持

java BIO:同步并阻塞

在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式!

服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善。

java NIO:同步非阻塞

在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要时不时的询问IO操作是否就绪,这就要求用户进程不停的去询问,从而引入不必要的CPU资源浪费。其中目前JAVA的NIO就属于同步非阻塞IO。

服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有I/O请求时才启动一个线程进行处理。

java AIO:异步非阻塞

在此种模式下,用户进程只需要发起一个IO操作然后立即返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。目前Java中还没有支持此种IO模型。 

服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是有OS先完成了再通知服务器应用去启动线程进行处理。

五、BIO、NIO、AIO适用场景分析

BIO方式适用于连接数目比较少且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,程序只管简单易理解。

NIO方式适用于连接数目多且比较短的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

AIO方式适用于连接数目多且连接比较长的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK1.7开始支持。

六、 Tomcat( BIO )和Jetty(NIO)

Tomcat和Jetty是目前全球范围内最著名的两款开源的webserver/servlet容器。

相同点:

1、Tomcat和Jetty都是一种servlet引擎,他们都支持标准的servlet规范和JavaEE的规范。

不同点:

1、架构比较

(1)Jetty的架构比Tomcat简单。

(2)Jetty的架构是基于handler来实现的,主要的扩展功能都可以使用handler来实现,扩展简单。

(3)Tomcat的架构是基于容器设计的,进行扩展是需要了解Tomcat的整体设计结构,不易扩展。

2、性能比较

(1)Jetty和Tomcat性能方面差异不大。

(2)Jetty可以同时处理大量连接而且可以长时间保持连接,适合web聊天应用等等。

(3)Jetty的架构简单,因此作为服务器,Jetty可以按需加载组件,减少不必要的组件,减少了服务器内部开销,从而提高服务器性能。

(4)Jetty默认采用NIO结束处理I/O请求上更占优势,在处理静态资源时,性能较高。

3、Tomcat适合处理少数非常繁忙的链接,Tomcat的总体性能更高。Tomcat默认采用BIO处理I/O请求,在处理静态资源时,性能较差。

4、其他比较

(1)Jetty的应用更加快速,修改简单,对新的servlet规范的支持较好。

(2)Tomcat目前应用比较广泛,对javaEE和servlet的支持更加全面,很多性能会直接集成进来。

 

一杯咖啡,一行代码,是一种境界,也是一种追求!

发布了110 篇原创文章 · 获赞 8 · 访问量 6914

Guess you like

Origin blog.csdn.net/guorui_java/article/details/104206704