Netty权威指南-笔记2-各I/O编程方式介绍

几种IO编程方式介绍

  • 传统BIO
  • NIO
  • AIO
  • 几种I/O模型对比

传统BIO

网络编程的基本模型是client/server模式,是两个进程之间进行通信。由服务端提供服务地址,客户端通过tcp连接,请求地址。BIO为同步阻塞模型,通常情况下,服务端由一个Acceptor来监听处理每一个client请求,接受到client请求后,会创建一个新的线程来处理client请求,处理完成后返回给client。这个模型种存在一个问题:就是当请求数量很大得时候,会创建很多线程,导致系统性能下降,并可能产生堆栈溢出等问题,最终导致服务不可用。如何处理解决这个问题?先卖个关子,请先思考。后面会给出优化建议。

NIO

NIO指的是非阻塞IO,使用nio的优点:

  • 异步:连接操作异步,独写操作异步,这样资源利用率较高。
  • 高性能、高负载:因为使用epoll,没有连接数限制,可以处理大量的请求,并且多路复用这种方式,只有活跃的线程会主动回调,所以性能很高。

NIO涉及的一些基本概念:

  1. 缓冲区Buffer:
    缓冲区本质上是一个数组,数组中存放要读或者写的数据,NIO中所有得数据都是通过缓冲区处理。在java中,每一种java基本类型都对应一种缓冲区,如ByteBuffer,CharBuffer等。
  2. 通道Channel
    如果将buffer比喻成一个水池,那Channel则是用来给水池输送水(也可以放水)的管道。它与传统的socket流的区别是:流(inputStream\outPutStream)只能是在一个方向上进行数据传输,不是输入流,就是输出流;而通道则没有这样的限制,既可以作为输入流,也可以作为输出流,甚至可以同时进行,用一个专业点的名词:全双工模式。
  3. 多路复用器selector
    selector,看名字就可以大概知道它的作用:选择。它提供了选择就绪通道的能力。通过轮询注册在其上的channel,根据channle的事件,获取对应事件的channel,进行后续的I/O操作。

AIO

相比较NIO1.0版本,NIO2.0增加了异步套接字通道,通过信号传递和回调完成操作,实现真正的异步。

介绍了几种I/O模型,回过头看前面的问题:BIO模型当请求量大的时候,性能会线性下降,如何优化?因为传统BIO模型客户端线程与服务线程是1:1的关系,如果客户端请求线程过多,则服务端线程也会很多,可能导致溢出。可以使用线程池的技术,指定固定线程和最大线程数量来避免处理这个问题。但是,由于线程池同样是同步阻塞的(伪异步),可能会导致队列种大量的任务堆积,同样可能会产生服务不可用的情况。这又该如何处理?可以使用NIO来解决这个问题。这也是使用NIO的原因。

几种I/O模型对比

同步阻塞IO(BIO) 伪异步IO 非阻塞IO (NIO) 异步IO(AIO)
客户端个数:I/O线程 1:1 M:N M:1 M:0
IO类型(阻塞) 阻塞 阻塞 非阻塞 非阻塞
IO类型(同步) 同步 同步 同步IO(多路复用) 异步IO

注:阻塞与非阻塞?同步和异步?怎么理解?
两者的关注点不同。阻塞与非阻塞关注的是客户端线程发起请求后,是否等待服务端响应。例如打电话:你给公司老王打电话,询问公司现在有多少人。老王回答说:稍等,去查一下。如果你没有挂断电话,在等待老王回复,则就认为是阻塞。如果你给老王说:那待会我再打给你。这种就是非阻塞的方式。
同步和异步关注的是客户端线程与服务端线程通信的一种机制,还是给老王打电话询问公司现在多少人。如果老王说稍等,我去查一下。此时你并未挂电话,再等老王回复,这种则是同步的。如果老王说你先挂了,待会我查过之后,我给你回电话通知你。此时你挂断电话处理其他事情,这种则是异步。
以上观点属于个人理解,不知道是否合理。如果不正确,还望评论区指正。

腹有诗书,才能胸有成竹

你可能感兴趣的:(读书笔记)