互联网中I/O流当中你所不知的概念,看完这篇将不再模糊
2020-01-27 本文已影响0人
javap
两组概念
I/O模型
理解NIO
两组概念
一、阻塞与非阻塞
阻塞与非阻塞是描述进程在访问某个资源时,数据是否准备就绪的的一种处理方式。当数据没有准备就绪时:
阻塞:线程持续等待资源中数据准备完成,直到返回响应结果。
非阻塞:线程直接返回结果,不会持续等待资源准备数据结束后才响应结果。
二、同步与异步
同步与异步是指访问数据的机制,同步-般指主动请求并等待IO操作完成的方式。异步则指主动请求数据后便可以继续处理其它任务,随后等待IO操作完毕的通知。
同步与异步针对的是应用程序,关注程序之间的协作状态;
- 同步请求一定有一个结果;
- 异步是不需要等待你的结果。
阻塞与非阻塞关注的是单个进程执行状态; - 不管你这个结果是否准备好,如果准备好这个结果才返回阻塞
- 不管你这个结果是否准备好,先给我一个结果非阻塞
-
理解用户空间(用户态)与内核空间(内核态)之间的数据传递过程。
异步IO模型
I/O模型
◆传统BIO模型
◆伪异步IO模型
◆NIO模型
传统BIO模型
- 传统BI0是一种同步的阻塞IO, IO在进行读写时,该线程将被阻塞,线程无法进行其它操作。
- 服务端接收到客户端的请求后,为每个客户端新创建一个线程。
- 在高性能服务器应用领域,往往需要面对成干上万个客户端的并发链接,这种模型显然无法满足高性能、高并发的场景。
BIO服务端通信模型,由一个独立的Acceptor线程负责监听客户端的连接,
Acceptor接收到客户端连接请求之后,为每个客户端建立一个新的线程进行链路处理。
处理完成之后,通过输出流返回应答给客户端,线程销毁。
阻塞IO模型
BIO模型存在的问题:
√ 性能问题:一连接一线程模型导致服务端的并发接入数和系统吞吐受到极大限制;
√ 可靠性问题:由于IO操作采用同步阻塞模式,当网络拥堵或者通信对端处理缓慢会导致IO线程被阻塞,且阻塞时间无法预测;
√ 可维护性问题: 10线程数无法有效控制、资源无法有效共享(多线程并发问题),系统可维护性差。
伪异步IO模型
以传统BIO模型为基础,通过线程池的方式维护所有的I0线程管理。
当有新的客户端连接时,将客户端的Socket封装为一个Task, 投递到一个线程池中进行处理。
但是底层实际还是采用同步阻塞IO模型,因此无法从根本上解决问题。
伪异步IO于某些客户端应答时间过长引起一些事故:
1、服务端处理缓慢,返回应答消息耗费60s,平常只需要10ms;
2、采用伪异步IO的线程正在读取故障服务节点的响应,由于读取输入流是阻塞的,它将会被同步阻塞60s;
3、如果所有的可用线程都被服务器阻塞,后续所有的IO消息都将在队列中排队;
4、由于线程池采用阻塞队列实现,当队列积满之后,后续入队列的操作将被阻塞;
5、由于前端只有一个Accptor线程接收客户端接入,它被阻塞在线程池的同步阻塞队列之后,新的客户端请求消息将被拒绝,客户端会发生大量的链接超时。
6、由于几乎所有的连接都超时,调用者会认为系统已经奔溃,无法接收新的请求消息。
NIO模型
NIO (JDK1.4) 模型是一种同步非阻塞I0,主要有三大核心部分: Channel(通道),Buffer(缓冲区),Selector (多路复用器)。传统IO基于字节流和字符流进行操作,而NIO基 于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(多路 复用器)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。
NIO的优点: - 客户端发起的连接操作是 异步的;
- SocketChannel的读写操作也是异步的;
-
线程模型的优化。
NIO流程图