一Netty框架--Java的IO演进

一Netty框架--Java的I/O演进

第一章 Java的I/O演进之路

1.1 I/O基础入门

Java1.4早期版本,对io支持不完善,存在如下问题:

buffer:没有数据缓冲区,io性能存在问题

channel:没有channel概念,只有输入InputStream和输出流OutputStream

同步阻塞:同步阻塞IO通信,会导致通信线程被长时间阻塞

支持字符集有限:支持有限,硬件移植性不好

1.1.1 Linux网络IO模型介绍

Linux内核将外部所有设备看作文件操作,对文件的读写操作,调用Linux内核提供的系统命令,返回file descriptor(fd,文件描述符)。对socket的读写也会有相应的描述符---socketfd。描述符作为一个数字,指向内核中一个结构体(文件路径、数据区等属性)。

UNIX网络编程对IO模型分类,为五种:

1 阻塞IO模型

常用的IO模型,默认情况,所有文件的读写都是阻塞模式。

image-20220911114135784

以socket为例讲解此模型:

进程空间中调用recvfrom,系统调用直到数据包到达且被复制到应用进程的缓冲区中/或者发生错误,才返回。系统进程在调用recvfrom到返回,整个过程是阻塞的,所以称为阻塞IO模型。

2 非阻塞IO模型

image-20220911115150451

​ recvfrom从应用层到内核的时候,如果缓冲区没有数据,直接返回EWOULDBLOCK错误,进程轮询检查该状态,循环调用recvfrom。

区别于阻塞IO模型:

​ 轮询方式检查EWOULDBLOCK状态,反复调用recvfrom。

3 IO复用模型

image-20220911114853645

​ (1)Linux提供select/poll,进程将一个或多个fd先传递给select/poll,然后阻塞在select/poll上,其可以帮助检测fd是否处于就绪状态。

(select、poll,是顺序扫描fd,且支持fd数量有限,使用受到制约)

​ (2)Linux提供epoll系统调用,其使用基于事件驱动方式代替顺序扫描,性能更高;当有fd就绪,立即回调rollback。

与netty关系:

在netty中为epoll单独开启线程。

多路复用器selector能够实现非阻塞的IO操作。

4 信号驱动IO模型

5 异步IO模型

image-20220911120613519

告知内核启动某个操作,在内核完成整个操作(将数据从内核复制到用户缓存区后),再通知我们。

区别于信号驱动模型:

​ 信号驱动IO由内核通知,何时开始进行IO操作的recvfrom;

​ 异步IO由内核通知,何时IO操作完成。

1.1.2 IO多路复用技术

技术适用

​ 处理多个客户端接入请求,可以用多线程或者多路复用技术。

核心:

​ IO多路复用技术,通过把多个阻塞的IO,复用到一个select的阻塞线程上(select监听注册在其上的fd的就绪状态),使得系统可以在单线程的情况下处理多个客户端请求。

优势:

​ 系统开销小、系统不需要开启额外的线程和进程处理就绪的fd、不需要维护线程和进程(指select)、节省系统资源。

应用场景:

​ 1 server负责处理多个处于监听状态或者连接状态的套接字socket;

​ 2 server需要处理多种网络协议的套接字

Epoll与select的区别

​ select是轮询网络就绪事件,效率低。

​ epoll,需要注册fd到epoll,然后事件驱动方式监听就绪的fd,有事件通知,立即执行rollback回调。

epoll总结如下:

​ 1 epoll支持一个进程打开的socketfd数量不受限制;

​ 2 IO效率不会随着fd数量增加而下降(epoll只针对注册在其上的socket中活跃的,进行操作——epoll通过fd上的callback函数实现,只有活跃或者就绪状态的fd回去调用callback。因此,不需要像select中进行线性扫描那样的低效操作)。

​ 3 使用mmap(用户空间),加速了内核和用户空间缓存的消息传递

select、poll需要内核把fd消息通知给用户空间缓存,不必要的复制,影响性能。epoll通过内核和用户空间mmap同一块内存。

​ 4 epoll的api简单

创建epoll描述符、添加监听事件、阻塞等待,监听事件的发生、关闭epoll

posted @ 2023-03-10 17:19  LeasonXue  阅读(22)  评论(0编辑  收藏  举报