Netty 之 Java 的 I/O 演进之路

说明

系列文章:http://www.jianshu.com/p/594441fb9c9e

本文完全参考自《Netty权威指南(第2版)》,李林峰著。

Linux 网络 I/O 模型

Linux内核将所有的外部设备都看做文件来操作,对文件的读写会调用内核的系统命令,返回一个file descriptor(fd,文件描述符)。而对一个socket的读写也会有相应的描述符,称为socketfd(socket描述符),指向内核中的一个结构体。

UNIX提供了5种I/O模型:

  1. 阻塞I/O模型:在进程中调用recvfrom,系统直到数据包到达且被复制到应用进程的缓冲区或发生错误才返回,在此期间一直会阻塞等待。进程在调用recvfrom开始到它返回的整段时间内都是被阻塞的,所以被称为阻塞I/O模型。
  2. 非阻塞I/O模型:recvfrom从应用层到内核时,如果该缓冲区没有数据,直接返回错误,一般对非阻塞I/O模型进行轮询状态检查,看内核是否有数据到来。
  3. I/O复用模型:Linux提供select/poll,进程将一个或多个fd传递给select/poll系统调用,阻塞在select操作上。select/poll顺序扫描fd是否准备就绪,而且支持的fd数量很有限。epoll是基于事件驱动方式代替循环扫描,性能更高;当有fd就绪时,立即回调函数rollback。
  4. 信号驱动I/O模型:系统调用sigaction执行信号处理函数(此系统调用立即返回,进程继续工作,它是非阻塞的)。当数据准备就绪时,为该进程生成一个SIGIO信号,通过信号回调通知应用程序调用recvfrom来读取数据。
  5. 异步I/O:告知内核启动某个操作,并让内核在整个操作完成后通知我们。与信号驱动模型的主要区别:信号驱动I/O由内核通知我们何时可以开始一个I/O操作;异步I/O模型由内核通知我们I/O操作何时已经完成。

I/O 多路复用技术

作用

在I/O编程过程中,当需要同时处理多个客户端接入请求时,有两种处理方式:

  • 多线程
  • I/O多路复用技术

那么I/O多路复用技术有什么好处呢?

把多个I/O的阻塞,复用到同一个select的阻塞上,从而使得系统通过单线程来同时处理多个客户端请求,节省系统资源。

应用场景

  • 服务器需要同时处理多个处于监听状态或连接状态的套接字;
  • 服务器需要同时处理多种网络协议的套接字。

支持 I/O 多路复用的模型有哪些?

  • select(有缺陷)
  • pselect
  • poll
  • epoll(使用)

epoll 有哪些优点?

  • 支持一个进程打开的socket描述符不受限制
  • I/O效率不会随着FD数目的增加而线性下降
  • 使用mmap加速内核与用户空间的消息传递
  • epoll的API更加简单

Java 的 I/O 演进

Java的I/O在1.4以前版本并不好,仅有非常基本的功能。

JDK 1.0 ~ JDK 1.3

1.0 ~ 1.3 中的Java I/O类库相当原始,很多UNIX网络编程中的概念都没有体现出来。

JDK 1.4 NIO

JDK 1.4中,NIO正式随JDK发布,新增了java.nio包,提供了异步I/O开发的API和类库

JDK 1.7 NIO 2.0

将原来的NIO类库进行了升级,成为NIO 2.0。

你可能感兴趣的:(Netty 之 Java 的 I/O 演进之路)