一章 Java IO 的演进之路
java基础入门 IO基础知识
-
1.4之前的版本
-
没有数据缓冲区,
-
没有Channel概念
-
同步阻塞I/O通信(BIO)导致通信线程被长时间阻塞
-
支持的字符集有限,硬件可移植性不好
-
-
Linux网络I/O模型简介
-
Linux的内核将所有外部设备都看做一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个file descriptor fd 文件描述符,而对一个socket的读写也会有相应的描述符,称为socketfd socket描述符,描述符就是一个数字,它指向内核中的一个结构体
-
Linux 提供了5种I/O模型
-
阻塞I/O模型
-
在进程空间中调用recvfrom,其系统调用直到数据包到达且被复制到进程的缓冲区中或者发生错误时才返回,在此期间会一直等待。
-
-
非阻塞I/O模型
-
recv从应用层到内核的时候,如果该缓冲区没有数据的化,就直接返回一个ewoludblock错误,一般都会非阻塞I/O模型进行轮询检查这个状态,看内核是不是又数据到来
-
-
I/O复用模型
-
Linux提供了select/poll,进程通过将一个或多给fd传递给select或poll系统调用。阻塞在select操作上,这样可以帮助我们侦测多给fd是否处于就绪状态。顺序扫描fd是否就绪,而且支持的fd数量有限
-
epoll系统调用,epoll使用基于事件驱动方式代替顺序扫描,性能更高,当又fd就绪时,立即回调函数 rollback
-
-
信号驱动I/O模型
-
开启套接口信号驱动I/O功能,并通过系统调用sigaction指向一个信号处理函数(此系统调用立即返回,进程继续工作,非阻塞)。当数据准备就绪时,就为该进程生成一个sigio信号,通过信号回调,通知应用程序调用recvfrom来读取数据,并通知主循环函数处理数据
-
-
异步I/O
-
告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核复制到用户自己的缓冲区)通知我们。
-
-
-
-
I/O多路复用技术
-
I/O多路复用技术通过把多个I/O的阻塞复用到同一个select的阻塞上,从而使得系统在单线的情况下可以同时处理多个请求的客户端请求。
I/O多路复用的最大优势是系统开销小,系统不需要创建新的额外进程或者线程,
-
应用场景
-
服务器需要同时处理多个监听状态或者多个来连接状态的套接字
-
服务器需要同时处理多种网络协议的套接字
-
支持I/O多路复用的系统调用又select,pselect,poll,epoll
-
-
epoll
-
1.支持一个进程打开的socket描述符fd不受限制(仅受限于操作系统的最大文件句柄数)
-
cat /proc/sys/fs/file-max 查看
-
select 默认1024
-
-
2.IO效率不会随着FD数码的增加而线性下降
-
select/poll每次调用都会进行线性扫描全部的集合,导致效率线性下降
-
epoll 只会对“活跃”的socket进行操作
-
在内核实现中,epoll是根据每个fd上面的callback函数实现的,那么只有活跃的socket才会主动的去调用callback函数,
-
epoll实现了一个伪AIO,
-
-
-
3.使用mmap加速内核与用户空间的消息传递
-
无论是select,poll,epoll都需内核把FD消息通知给用户空间,如何避免不必要的内存复制就显的非常重要,epoll是通过内核和用户空间Mmap同一块内存实现的
-
-
4.epoll的API更加简单
-
创建一个epoll描述符,添加一个监听事件,阻塞等待所监听的事件发生,关闭描述符
-
-
-
java的IO演进
-
环境
-
采用Java BIO开发的服务器端软件,只有通过硬件的不断扩容来满足,高并发,低时延,极大的增加了成本。随着集规模的不断膨胀,系统的可维护性也面临巨大的挑战。
-
-
发展简史
-
jdk1.0 - 1.3 非常原始
-
2002 1.4 NIO JSR-51 java.nio
-
进行异常I/O操作的缓存区 ByteBuffer;
-
进行异步I/O操作的管道 Pipe;
-
进行各种I/O操作的channel,包括ServerSocketChannel,和SocketChannel
-
各种字符集的编码能力和解码能力
-
实现非阻塞I/O操作的多路复用器selector
-
perl正则表达式库
-
文件通道FileChannel
-
-
20011 1.7 NIO2 JSR-203
-
提供了批量活动文件的属性的API
-
提供了AIO
-
JSR-51定义的通道功能,
-
-
总结
1.我们了解了5种网络模型,
2.学习了I/O多路复用技术的基础
借鉴书籍:
《权威指南》李林峰