一、五种网路通讯IO模型
1.阻塞 同步阻塞 请求响应
2.非阻塞 同步非阻塞 过一会问一下,没数据前可以干别的
3.多路复用 伪异步( 同步)非阻塞 没有之前阻塞,有数据读取(20200828修改多路服用IO模型为同步非阻塞,原因是:
对于每一个socket,一般都设置成非阻塞,但是整个用户的进程其实一直是被阻塞的,只不过进程是被select函数阻塞,而不是被socket I/O阻塞)
4.信号驱动 伪异步(同步)非阻塞,没有之前干别的,有数据读取
5.异步 异步非阻塞
二、概念区分
1、同步和异步
看请求的数据是需要用户线程主动去系统内核获取的还是由操作系统直接从内核空间内存拷贝到用户空间内存的,前面四中IO模型都是主动获取,只有异步IO模型是由操作系统直接从内核空间内存拷贝到用户空间内存,数据拷贝好后被动通知用户线程的
2、阻塞和非阻塞
看调用I/O操作的线程是否被挂起,如果不管有没有结果都立即返回则是非阻塞,比如阻塞IO线程等待结果(阻塞io模型)属于阻塞的;而非阻塞IO模型、信号驱动IO模型、多路复用IO模型、异步IO模型都是非阻塞的。
三、五种IO模型
1、阻塞IO模型
1)系统调用
recvfrom....返回结果
2)通讯模型
BIO通讯模型服务端:
通常由一个独立的Acceptor线程负责监听客户端连接,接收到客户端连接后,为客户端连接创建一个新的线程处理请求,处理完后,返回消息给客户端,线程销毁,这就是典型的1请求/1应答模型。
3)线程模型
采用BIO模型,使得每个TCP连接都需要分配1个线程
4)缺点
传统RPC调用性能的【三宗罪】
1、网络传输方式:基于BIO,当客户端连接多或者网络延迟时,I/O线程经常阻塞,导致IO线程无法高效被利用;这样的通讯模型,当用户访问量增大时,并发量上升,导致服务端创建的线程数量增加(如果使用线程池限制客户端连接数则会降低服务端能够接受连接的客户端数量),而线程时JVM非常宝贵的系统资源,所以随着并发量的增加、线程数膨胀,会导致系统性能急剧下降,可能会发生句柄溢出和线程堆栈溢出等问题,最终会导致服务器宕机
2、线程模型:每个TCP连接都需要分配1个线程,而线程资源是JVM非常宝贵的资源,当I/O读写阻塞导致线程无法及时释放时,会导致系统性能急剧下降,甚至会导致虚拟机无法创建新的线程。
3、序列化方式存在弊端:java序列化机制存在如下问题:
- 无法跨语言
- 占用的空间大:相比于其他开源的序列化框架,Java序列化后的字节码流占用的空间太大,无论是网络传输还是持久化到硬盘,都会增加资源的消耗
- 序列化性能较差:在编解码过程中需要占用更高的CPU资源
2、非阻塞IO模型
系统调用
recvfrom....error
recvfrom....error
recvfrom....error
...
recvfrom....返回结果
3、多路复用IO模式
系统调用
select.....阻塞,返回数据准备好了
recvfrom....返回结果
4、信号驱动IO模型
5、异步IO模型
系统调用
ia_read