当前位置:网站首页>【RPC】I/O模型——BIO、NIO、AIO及NIO的Rector模式
【RPC】I/O模型——BIO、NIO、AIO及NIO的Rector模式
2022-06-25 09:39:00 【牧心.】
文章目录
1. I/O模型
1.1 用户进程与系统进程
在了解I/O操作的过程之前,先介绍一下什么是用户进程和系统进程:
- 用户进程:通过执行用户进程或内核之外的程序而产生的进程,该类进程可以在用户的控制下运行或者关闭。
- 系统进程:可以执行内存资源分配和进程切换等管理操作,系统进程一般无法使用用户权限进行控制。
用户进程所在的区域叫做用户空间,系统进程所在的区域叫做内核空间。
用户进程不可以直接访问系统数据或者资源,他没有办法从内核态空间直接获取资源,需要将数据从内核态空间复制到用户空间,再获取用户空间中的数据。处于用户态的程序只能访问用户空间,只有处于内核态的程序才可以访问用户空间和内核空间。
如果用户进程需要访问系统资源或者使用系统数据,则必须调用操作系统提供的接口。这个调用接口的过程就是用户态进程主动要求从用户态切换到内核态的一种方式,也就是平常所说的系统调用。
1.2 一次I/O操作经历了什么?
以一次数据的读取为例,无论磁盘I/O还是网络I/O,第一步都是用户进程等待内核准备数据,内核准备数据的阶段会将数据复制到内核空间,用户进程也从用户态转变为内核态。磁盘I/O和网络I/O唯一不同的是磁盘I/O中内核从磁读取磁盘数据,而在网络I/O中内核从网卡中读取流数据。数据准备完毕收,第二步就是从内核空间将数据复制到目标用户空间供用户进程读取。
1.3 I/O模型是什么?
了解了一次I/O操作的过程后,那么平常说的I/O模型又是什么呢?
I/O模型可以理解为机器上进行数据读/写调度的策略模型。
I/O模型可以从两个维度去理解:
1)阻塞与非阻塞。用户进程发起I/O操作后,根据是否需要等待I/O操作完成才能继续运行,可以分为阻塞与非阻塞两种。
2)同步与异步。在用户进程发起I/O操作后,会由用户态转变为内核态,内核进程在完成复制数据的操作后执行I/O操作,操作执行完成后,需要从内核态转变为用户态,并且需要执行复制数据的操作。
- 如果是同步I/O操作,则在将数据复制到用户空间的过程中,用户线程会阻塞。
- 如果是异步I/O操作,则内核线程直接执行复制数据到用户空间,完成复制数据的操作后才通知用户进程I/O操作完成,不会造成用户线程直接执行复制数据的时候阻塞。也就是内核进程负责将数据复制到用户进程,用户进程可以直接执行后续操作。
同步和异步针对的对象是内核进程。
Linux有5种I/O模型,分别是:
- BIO(Blocking I/O):用户进程发起I/O操作后,内核进入数据准备阶段。数据还未全部准备好时,内核一直处于数据准备节点,而用户进程也被阻塞。
- NIO(Non-blocking I/O):用户进程发起I/O操作后,内核进入数据准备阶段。数据还未全部准备好时,内核一直处于数据准备阶段,而用户进程暂时先去做其他事情,但是用户进程会每隔一段时间询问数据是否准备好了。一旦准备好了,用户进程将会继续后续的操作。
- I/O Multiplexing:该模型主要是单个进程就可以同时处理多个网络连接的I/O模型,本质上用户进程还是阻塞的,但是select不会被阻塞,select/poll/epoll的方法不断地轮询所负责的而所有Socket,当某个Socket有数据到达时,就通知对应的用户进程。
- Singal Driven I/O:当用户进程执行I/O操作(读或写)时,内核马上返回,进程继续运行,在内核进程完成I/O操作(或出错)后,通过信号通知进程。
- AIO(Asychronous I/O):内核线程直接执行复制数据的过程,完成数据复制后才通知用户进程I/O操作完成,不会造成用户线程在复制数据的时候阻塞。
前四种是同步的,最后一种是异步的。
2. Java对I/O模型的封装
Java对I/O模型的封装可以分为BIO、NIO和AIO三种。
2.1 BIO
一个客户端的连接请求被接收器接收后,在服务端会创建一个线程与该客户端进行通信,这个线程一般会执行读取、解码、计算、编码、发送这几个步骤。
这种模式非常耗费系统资源,首先在服务器端需要一个接收器一直处于阻塞状态等待新的客户端请求,其次每当有新的客户端请求连接时,都需要创建新的线程来处理请求,每个线程在处理完请求后都需要销毁。线程的创建和销毁会占用系统资源。
于是在该架构上又增加了线程池的设计,如下图:
当服务端收到客户端的连接请求后,作为一个任务丢给线程池,让线程池来分配线程执行与客户端通信的逻辑。
虽然加入线程池的设计可以提升系统性能,但是当请求量增大、线程数过高时,线程池频繁切换线程带来的成本问题也会暴露出来;并且在服务端需要一个线程一直阻塞等待客户端的连接请求,在客户端的线程也会因为服务端还没有把请求结果返回而一直阻塞等待。
2.2 NIO
Java NIO和Linux中的非阻塞I/O有一些区别,他更像是Linux中的非阻塞多路复用I/O,它可以帮助Java并发构建同步非阻塞的多路复用I/O应用程序,同时提供更接近底层高性能的数据操作方式,并且它还支持select/poll模型,在JDK1.5之后又增加了对epoll的支持。
介绍一下三个重要的概念:
Channel(通道):Java提供了四种Channel,分别是FileChannel(用于文件操作)、SocketChannel(用于客户端TCP操作)、ServerSocketChannel(用于服务端TCP操作)、DatagramChannel(用于UDP操作)。
- Channel是一个双向的数据读、写通道。 Channel可以实现读和写同时操作,并且同时支持阻塞和非阻塞模式。
- 一个客户端连接对应一个Channel,当有新的连接请求时,会向Selector中注册一个Channel,并且会将Channel与对应的事件处理器进行绑定。
- 事件处理器包含该通道里面的各类事件对应的处理逻辑,事件处理器一共有4中,分别是读数据事件处理器、写数据事件处理器、连接事件处理器、接受事件处理器。
Buffer(缓冲区):可以将Buffer看作一个存储数据的容器,Channel可以对Buffer进行读/写操作,并且所有数据的读/写都会经过缓冲区。在NIO中,有两种不同的缓冲区:
- 直接缓冲区:可以直接操作JVM的堆外内存,即在系统内核缓存中分配的缓冲区,通过allocateDirect()方法可以分配直接缓冲区。
- 非直接缓冲区:只能操作JVM的堆中内存,通过allocate()方法可以分配非直接缓冲区。
Buffer有许多实现,比如ByteBuffer、CharBUffer、LongBuffer等,分别对应一种数据类型的实现。
Selector(选择器):Selector通过不断轮询注册在其上的Channel来选择分发已处理就绪的事件,这里的事件有四种,分别是连接事件、接收连接事件、读事件和写事件。
- Selector可以同时轮询和监控多个Channel,当Selector发现某个Channel的数据状态发生变化时,会通过SelectorKey出发相关事件,并由对此事件感兴趣的事件处理器来执行相关逻辑,数据则从Buffer中获取,执行完成后再写回Buffer,以供Channel读取。
了解了以上概念之后,整个NIO的处理过程也就比较简单明了了。从上面的处理结构图可以看到,当一个客户端连接到来时,服务端会为这个新的连接创建一个Channel,并将这个Channel注册到Selector上,Selector会监控所有注册在自己身上的Channel,一旦某个Channel的数据状态发生改变,比如数据读取完毕,则会触发相关的事件。Channel的数据读取和写入都只与Buffer进行交互。
下文待续~
2.3 NIO的Rector模式
2.3.1 单Rector单线程模型
2.3.2 单Rector多线程模型
2.3.3 主从Rector多线程模型
2.4 AIO
参考资料:《深入理解RPC框架原理与实现》 华钟明著.
边栏推荐
- IdentityServer4 定义概念
- Kotlin advanced set
- Gradle download warehouse is slow
- 字符串 实现 strStr()
- MySQL创建给出语句
- Set the location permission in the shutter to "always allow"
- How much does a small program cost? How much does a small program cost? It's clear at a glance
- 链表 删除链表中的节点
- Principle of distribution: understanding the gossip protocol
- Best producer consumer code
猜你喜欢
i++ 和 ++i的真正区别
ShardingSphere-Proxy 4.1 分库分表
Minio基本使用与原理
[MySQL learning notes 21] storage engine
Redis(一)原理与基本使用
2台三菱PLC走BCNetTCP协议,能否实现网口无线通讯?
如何在Microsoft Exchange 2010中安装SSL证书
Nano data World Cup data interface, CSL data, sports data score, world cup schedule API, real-time data interface of football match
链表 删除链表中的节点
Huipay international permet au commerce électronique transfrontalier de devenir une plate - forme de paiement transfrontalière conforme!
随机推荐
依赖属性、依赖附加属性以及类型转换
Pytorch_Geometric(PyG)使用DataLoader报错RuntimeError: Sizes of tensors must match except in dimension 0.
Flask博客实战 - 实现个人中心及权限管理
Ruiji takeout project (II)
Methodchannel of flutter
[MySQL learning notes 20] MySQL architecture
Redis (II) distributed locks and redis cluster construction
What should be paid attention to in PMP examination?
Mengyou Technology: tiktok live broadcast with goods elements hot topics retention skills shaping image highlight selling points
8. Intelligent transportation project (1)
Tiktok brand goes to sea: both exposure and transformation are required. What are the skills of information flow advertising?
clang frontend command failed with exit code 250
Webapi performance optimization
SparseArray details
Puzzle (019.2) hexagonal lock
Houdini图文笔记:Your driver settings have been set to force 4x Antialiasing in OpenGL applications问题的解决
Learning notes of rxjs takeuntil operator
字符串 最长公共前缀
Notes on writing questions in C language -- monkeys eat peaches
Redis (I) principle and basic use