《Netty权威指南》第一章-Java 的 IO 演进之路

文章目录

  • 1.1 I/O 基础入门
    • 1.1.1 Linux 网络 I/O 模型简介
    • 1.2.2 I/O 多路复用技术
  • 1.2 Java 的 I/O 演进
  • 1.3 总结

1.1 I/O 基础入门

JDK 1.4 之前

  • 没有数据缓冲区,I/O性能存在问题
  • 没有C或者C++中的Channel概念,只有输入和输出流;
  • 同步阻塞式I/O通信(BIO),通常会导致通信线程被长时间阻塞;
  • 支持的字符集有限,硬件可移植性不好。

1.1.1 Linux 网络 I/O 模型简介

文件描述符(lile description,fd)

Linux 内核将所有外部设备看出文件夹,对文件的操作会返回一个描述符。描述符是一个数字,指向内核中的一个结构体(文件路径、数据去等属性)。

socket 描述符(socketfd):对 socket 的读写。

5 种 I/O 模型

  1. 阻塞 I/O模型:阻塞等待调用结果
  2. 非阻塞 I/O 模型:轮询检查调用结果
  3. I/O 复用模型:
    • select/pool:阻塞在 select 上,顺序扫描 fd 是否就绪,支持数量有限 1024
    • epool:基于事件驱动,fd 就绪触发回调函数
  4. 信号驱动 I/O 模型:通知 I/O 操作可以开始
  5. 异步 I/O:通知 I/O 操作完成

1.2.2 I/O 多路复用技术

场景

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

方案演进

  • 使用多线程:每个连接对应一个线程
  • I/O 多路复用:多个 I/O 阻塞到同一个 select 上
    • 使用 epoll,改进 select
    • 一个进程打开的 socket 描述符仅受限于操作系统的最大文件句柄数
    • I/O 效率稳定,不随着 FD 数目增加而线性下降
    • 使用 mmap 加速内核与用户空间消息传递,内核与用户空间 mmap 同一块内存
    • epoll 设计更简单的 API

1.2 Java 的 I/O 演进

BIO,JDK1.0-1.3

  • 没有数据缓冲区,I/O性能存在问题
  • 没有C或者C++中的Channel概念,只有输入和输出流;
  • 同步阻塞式I/O通信(BIO),通常会导致通信线程被长时间阻塞;
  • 支持的字符集有限,硬件可移植性不好。

BIO,JDK1.4

提供新功能

  • 进行异步I/O操作的缓冲区ByteBuffer等
  • 进行异步I/O操作的管道Pipe
  • 进行各种I/O操作(异步或者同步)的Channel,包括ServerSocketChannel和SocketChannel
  • 多种字符集的编码能力和解码能力
  • 实现非阻塞I/O操作的多路复用器selector
  • 基于流行的Perl实现的正则表达式类库
  • 文件通道FileChannel

缺陷

  • 没有统一的文件属性(例如读写权限)
  • API能力比较弱,例如目录的级联创建和递归遍历,往往需要自己实现
  • 底层存储系统的一些高级API无法使用
  • 所有的文件操作都是同步阻塞调用,不支持异步文件读写操作

NIO2,JDK7

  • 提供能够批量获取文件属性的API,这些API具有平台无关性,不与特性的文件系统相耦合,另外它还提供了标准文件系统的SPI,供各个服务提供商扩展实现
  • 提供AIO功能,支持基于文件的异步I/O操作和针对网络套接字的异步操作
  • 完成JSR-51定义的通道功能,包括对配置和多播数据报的支持等

1.3 总结

本章首先介绍了 UNIX 网络编程的 5 种 I/O 模型;然后简述了 I/O 多路复用技术,重点阐述了支持多路复用的 epool 对 select 的改进;最后介绍了 Java 的 I/O 演进历史,让我们对每种 I/O 的优缺点有了大致了解。

你可能感兴趣的:(《Netty权威指南》)