以下几台Web服务器的I / O策略是什么?

时间:2018-08-20 15:09:42

标签: node.js asynchronous webserver tornado

有五种基本的I / O模型:

  • 阻止IO
  • 无阻塞IO
  • IO多路复用
  • 信号驱动的IO
  • 异步IO

我想知道在nodejs和龙卷风中使用哪一个?(可能是3号还是4号?)

有没有使用真正的异步IO(第5个,使用aio_xxx lib)的Web服务器?

2 个答案:

答案 0 :(得分:0)

nodejs中使用的非阻塞I / O,龙卷风使用了异步和非阻塞模型,因为一个操作可以同时激活。 NGINX服务器也使用异步。

答案 1 :(得分:0)

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

答案很长:

Nodejs对所有I / O使用一个名为libuv的库。如下图所示(来自http://docs.libuv.org/en/v1.x/design.html),libuv在内部使用系统调用epoll(在Linux中),kqueue(在Free BSD中),事件端口(在Solaris)和IOCP(在Windows中)。

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

  1. 应用程序线程将所需的文件描述符注册到内核中
  2. 内核将这些数据维护在其自己的内部数据结构中。它还维护所有应用程序线程的列表,以针对每个文件描述符唤醒。这样,当文件描述符(套接字)准备好进行读取(套接字缓冲区已充满数据)或写入(缓冲区为空以用于写入数据)时,内核就可以有效地唤醒线程。
  3. 内核还进行了其他优化,例如合并单个文件描述符的多个事件

这个想法主要起源于paper by Banga et al,它激发了kqueueepoll的发展。

即使在这些系统调用可用之前,I / O复用仍以无法很好扩展的系统调用selectpoll的形式存在。 selectpoll主要要求应用程序线程在每次调用时提交他们感兴趣的文件描述符列表。对于这些系统调用,内核是无状态的。这导致内核和应用程序多次扫描列表,从而导致可伸缩性问题。

现在关于异步I / O,我认为它主要是指POSIX AIO规范。给定通过I / O复用处理网络I / O的方式,POSIX规范仅对磁盘I / O有用。但是,libuv不使用它,并且可能是任何Web服务器都不使用它,主要是因为实现不佳,并非所有磁盘操作都可以是异步的,等等。提到了libuv不使用它的原因的详细列表{{3} }。

here