网络IO模型

  • 多路复用:是通信领域的术语,指把多个信号组合起来在一条物理信道上进行传输,在远距离传输时可大大节省电缆的安装和维护费用。这里指让一个线程或进程同时处理多个网络连接
  • 事件多路分离(Event Demultiplexer):分离器对象可将来自事件源的I/O事件分离出来,并分发到对应的read/write事件处理器(Event Handler)。开发人员预先注册需要处理的事件及其事件处理器(或回调函数);事件分离器负责将请求事件传递给事件处理器(an object that dispatches I/O events from a limited number of sources to the appropriate read/write event handlers. The developer registers interest in specific events and provides event handlers, or callbacks. The event demultiplexor delivers the requested events to the event handlers.)
  • 可以将输入操作io分为两个步骤:
    * 内核等待数据准备好;
    * 将数据从内核缓冲区复制到进程缓冲区
    

Linux系统支持的典型I/O模型包含下面5种:

  1. 阻塞I/O(blocking I/O)
  2. 非阻塞I/O(nonblocking I/O)
  3. I/O多路复用(I/O multiplexing, e.g. select and poll)
  4. 信号驱动型I/O(signal driven I/O, e.g. SIGIO)
  5. 异步I/O(asynchronous I/O, e.g. the POSIX aio_* functions)

同步(synchronous):A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes.

异步(asynchronous):An asynchronous I/O operation does not cause the requesting process to be blocked.

按照这种定义,上面介绍的前4中IO模型均是同步的,因为真正的IO操作函数在进行数据读/写时,均会阻塞进程;只有异步IO模型真正符合异步IO操作的定义。

同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO。

阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。

  • 传统的Java BIO (blocking I/O)是Unix I/O模型中的第一种。
  • Java NIO中如果不使用select模式,而只把channel配置成nonblocking则是第二种模型。
  • Java NIO select实现的是一种多路复用I/O。 底层使用epoll或者相应的poll系统调用
  • 第四种模型JDK应该是没有实现。
  • Java NIO2增加了对第五种模型的支持,也就是AIO。

Java 和Netty epoll实现

Oracle JDK在Linux已经默认使用epoll方式, 为什么netty还要提供一个基于epoll的实现呢?

Netty的核心开发者 Norman Maurer这么说的:

  • Netty的 epoll transport使用 epoll edge-triggered(边缘触发) 而 java的 nio 使用 level-triggered(水平触发)
  • 另外netty epoll transport 暴露了更多的nio没有的配置参数, 如 TCP_CORK, SO_REUSEADDR等等

References

  1. IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
  2. 五种IO模型
  3. Netty NIO 2 Support Discussion
  4. 网络IO模型
  5. Java BIO NIO AIO理解
  6. 鸟窝:java aio 编程
  7. I/O Demystified

results matching ""

    No results matching ""