Node.js 以下几种web服务器的I/O策略是什么?

Node.js 以下几种web服务器的I/O策略是什么?,node.js,asynchronous,webserver,tornado,Node.js,Asynchronous,Webserver,Tornado,有五种基本I/O模型: 阻塞IO 非阻塞IO IO多路复用 信号驱动IO 异步IO 我想知道哪一个是在nodejs和tornado中使用的?(可能是第三个还是第四个?) 是否有一个web服务器使用真正的异步IO(第五,使用aio_xxx lib)?在nodejs中使用非阻塞I/O,tornado使用异步和非阻塞模式,因为一个操作可以同时激活。 此外,NGINX服务器还使用了异步 简单的回答是,NodeJs使用I/O多路复用进行网络I/O,并使用带线程池的阻塞I/O进行磁盘I/O 答案很长:

有五种基本I/O模型:

  • 阻塞IO
  • 非阻塞IO
  • IO多路复用
  • 信号驱动IO
  • 异步IO
我想知道哪一个是在nodejs和tornado中使用的?(可能是第三个还是第四个?)


是否有一个web服务器使用真正的异步IO(第五,使用aio_xxx lib)?

在nodejs中使用非阻塞I/O,tornado使用异步和非阻塞模式,因为一个操作可以同时激活。
此外,NGINX服务器还使用了异步

简单的回答是,NodeJs使用I/O多路复用进行网络I/O,并使用带线程池的阻塞I/O进行磁盘I/O

答案很长:

Nodejs为所有I/O使用一个名为libuv的库。如下图所示(取自),libuv在内部使用系统调用
epoll
(在Linux中)、
kqueue
(在免费BSD中)、事件端口(在Solaris中)和IOCP(在Windows中)

这些系统调用基本上是I/O多路复用(网络I/O,而不是磁盘I/O)。这里的关键思想是:

  • 应用程序线程向内核注册它感兴趣的文件描述符
  • 内核在自己的内部数据结构中维护这些数据。它还维护了所有应用程序线程的列表,以便根据每个文件描述符进行唤醒。这允许内核在文件描述符(套接字)准备好读取(套接字缓冲区充满数据)或写入(缓冲区为空以写入数据)时高效地唤醒线程
  • 内核还进行其他优化,例如合并单个文件描述符的多个事件
  • 这一想法主要起源于一个激发了
    kqueue
    epoll
    开发的项目

    甚至在这些系统调用可用之前,I/O多路复用就以系统调用
    select
    poll
    的形式存在,但扩展性不好
    select
    poll
    主要要求应用程序线程在每次调用中提交他们感兴趣的文件描述符列表。对于这些系统调用,内核是无状态的。这导致内核和应用程序对列表进行多次扫描,从而导致可伸缩性问题

    至于异步I/O,我认为它主要是指POSIX AIO规范。考虑到通过I/O多路复用处理网络I/O的方式,POSIX规范可能仅对磁盘I/O有用。但是,libuv不使用它,而且可能任何web服务器都不使用它,主要是因为实现不好,并非所有磁盘操作都可以是异步的等等。下面列出了libuv不使用它的详细原因