Netty之Java I/O演进之路(一)
文章目录
- I/O基础入门
- Linux 网络 I/O模型简介
- 多路复用技术
- Java 的 I/O 演进
I/O基础入门
Java1.4之前的IO并不完善,只有同步阻塞的BIO,通常导致通信线程长时间阻塞,直到之后的NIO出现。
Linux 网络 I/O模型简介
Linux的内核将所有外部设备都看做一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令,返回一个 file descriptor(fd,文件描述符)。而对一个 socket的读写也会有相应的描述符,称为 socketed( socket描述符),描述符就是一个数字,它指向内核中的一个结构体(文件路径,数据区等一些属性) ——Netty权威指南
说人话:每个文件都有他的一个fd(可以当作一个指针来理解,或者当作一个索引来理解
)如果想要读取一些文件,就要保证这些文件不被占用并且可读,就是通过这个fd来判断的。
举个栗子:现在来了3个连接想要读取A、B、C、D、E、F五个资源,那么第一个连接优先拿到访问权,去读取这五个资源,然后其他两个连接就需要等待第一个连接操作结束,所以其他两个连接中间的操作就是等待这五个资源不被占用,如果是select(下面会讲到),这两个连接就在不停的轮询这五个资源的fd是否可用。
根据UNIX网络编程对1O模型的分类,UNIX提供了5种10模型,分别如下:
- 阻塞I/O模型
- 非阻塞I/O模型
- IO复用模型
- 信号驱动IO模型
- 异步IO
多路复用技术
目前支持IO多路复用的系统调用有 select、 select、poll、 epoll,在 Linux网络编程过程中,很长一段时间都使用 select做轮询和网络事件通知,然而 select的一些固有缺陷导致了它的应用受到了很大的限制,最终 Linux不得不在新的内核版本中寻找 select的替代方案,最终选择了 epoll. epoll与 select的原理比较类似,为了克服 select的缺点, epoll作了很多重大改进。 ———-Netty权威指南
select
select最大的缺陷就是单个进程所打开的FD是有一定限制的,它由FD SETSIZE
设置,默认值是1024
也就是说,连接上来的线程最多只能是1024
个,对于那些需要支持上万个TCP连接的大型服务器来说显然太少了,当然我们可以修改这个值,但是会带来网络效率下降
传统的 select/poll另ー个致命弱点就是当你拥有一个很大的 socket集合,由于网络延时或者链路空闲,任一时刻只有少部分的 socket是“活跃”的,但是 select/pol每次调用都会线性扫描全部的集合
,导致效率呈现线性下降
epoll
epoll 并没有这个限制,它所支持的FD上限是操作系统的最大文件句柄数,这个数字远远大于1024.
例如,在1GB内存的机器上大约是10万个句柄
左右,具体的值可以通过 cat /proc/sys/fs/file-max察看,通常情况下这个值跟系统的内存关系比较大
epoll不存在像select扫描那个问题,它只会对“活跃”的 socket进行操作-这是因为在内核实现中epoll是根据每个fd上面的 callback函数实现的,那么,只有“活跃”的 socketオ会主动的去调用 callback函数,其他ide状态 socket则不会如果所有的 socket都处于活跃态-例如一个高速LAN环境, epoll并不比select/poll效率高太多
Java 的 I/O 演进
- 同步阻塞IO BIO 1.4之前
从JDK1.0到JDK1.3,Java的IO类库都非常原始,很多UNIX网络编程中的概念或者接口在1/O类库中都没有体现,例如Pipe、 Channel、 Buffer和 Selector等。2002年发布JDK1.4时,NIO以JSR-51的身份正式随JDK发布。它新增了个java.nio包,提供了很多 - 非阻塞IO NIO 1.4之后
新的NIO类库的提供,极大地促进了基于Java的异步非阻塞编程的发展和应用,但是,它依然有不完善的地方,特别是对文件系统的处理能力仍显不足,主要问题如下:
没有统一的文件属性(例如读写权限)
API能力比较弱,例如目录的级联创建和递归適历,往往需要自己实现底层存储系统的一些高级API无法使用
所有的文件操作都是同步阻塞调用,不支持异步文件读写操作 - NIO2.0 1.7
2011年7月28日,JDK1.7正式发布。它的一个比较大的亮点就是将原来的NIO类库进行了升级,被称为NIO2.0.NIO2.0由JSR-203演进而来,它主要提供了如下三个方面的改进:
提供能够批量获取文件属性的API,这些API具有平台无关性,不与特性的文件系统相耦合,另外它还提供了标准文件系统的SPI,
供各个服务提供商扩展实现提供AO功能,支持基于文件的异步I/O操作和针对网络套接字的异步操作
完成JSR-51定义的通道功能,包括对配置和多播数据报的支持等
Netty之Java I/O演进之路(一)
Netty之NIO入门(二)
Netty之Netty入门应用(三)
Netty之TCP粘包/拆包问题(四)
Netty之编解码开发(五)
Netty之ChannelPipeline(六)
Netty之EventLoop和EventLoopGroup(七)
还没有评论,来说两句吧...