【问题标题】:Is 'epoll' the essential reason that Tornadoweb(or Nginx) is so fast?'epoll' 是 Tornadoweb(或 Nginx)如此之快的根本原因吗?
【发布时间】:2011-02-04 17:11:33
【问题描述】:

TornadowebNginx 是目前流行的 Web 服务器,许多基准测试表明它们在某些情况下比 Apache 具有更好的性能。所以我的问题是:

'epoll' 是让它们如此之快的最根本原因吗?如果我想写一个好的套接字服务器,我能从中学到什么?

【问题讨论】:

    标签: apache nginx tornado epoll


    【解决方案1】:

    如果您正在寻找编写套接字服务器,一个很好的起点是 Dan Kegel 几年前的 C10k 文章:

    http://www.kegel.com/c10k.html

    我还发现 Beej 的网络编程指南非常方便:

    http://beej.us/guide/bgnet/

    最后,如果您需要很好的参考资料,可以阅读 W. Richard Stevens 等人的 UNIX Network Programming。人:

    http://www.amazon.com/Unix-Network-Programming-Sockets-Networking/dp/0131411551/ref=dp_ob_title_bk

    无论如何,回答您的问题,Apache 和 Nginx 之间的主要区别在于 Apache 每个客户端使用一个线程并具有阻塞 I/O,而 Nginx 是单线程且具有非阻塞 I/O。 Apache 的工作池确实减少了启动和销毁进程的开销,但是在为多个客户端提供服务时,它仍然使 CPU 在多个线程之间切换。另一方面,Nginx 在一个线程中处理所有请求。当一个请求需要发出网络请求(例如,到后端)时,Nginx 将回调附加到后端请求,然后处理另一个活动的客户端请求。在实践中,这意味着它返回到事件循环(epollkqueueselect)并要求提供需要报告的文件描述符。请注意,主事件循环中的系统调用实际上是一个阻塞操作,因为在其中一个文件描述符准备好进行读取或写入之前,什么都不做。

    这就是 Nginx 和 Tornado 能够高效地同时为许多客户端提供服务的主要原因:只有一个进程(从而节省 RAM)和一个线程(从而从上下文切换中节省 CPU)。至于epoll,它只是select的一个更高效的版本。如果有 N 个打开的文件描述符(套接字),它可以让您在 O(1) 而不是 O(N) 时间内挑选出准备读取的文件描述符。事实上,如果你使用--with-select_module 选项编译 Nginx,它可以使用 select 而不是 epoll,我敢打赌它仍然会比 Apache 更高效。我对 Apache 内部结构不太熟悉,但是快速 grep 显示它确实使用了 select 和 epoll —— 可能是在服务器正在侦听多个端口/接口时,或者如果它同时为单个客户端执行后端请求。

    顺便说一句,我开始尝试编写一个基本的套接字服务器,并想弄清楚 Nginx 是如何如此高效的。在仔细研究了 Nginx 源代码并阅读了我上面链接的那些指南/书籍之后,我发现编写 Nginx 模块而不是我自己的服务器会更容易。因此诞生了现在半传奇的 Emiller 的 Nginx 模块开发指南:

    http://www.evanmiller.org/nginx-modules-guide.html

    (警告:该指南是针对 Nginx 0.5-0.6 编写的,API 可能已更改。)如果您使用 HTTP 做任何事情,我会说给 Nginx 一个机会,因为它已经解决了所有棘手的处理细节愚蠢的客户。例如,我为好玩而编写的小型套接字服务器在所有客户端上都能很好地工作——除了 Safari,我从来不知道为什么。即使对于其他协议,Nginx 也可能是正确的选择;事件从协议中很好地抽象出来,这就是它可以代理 HTTP 和 IMAP 的原因。 Nginx 代码库组织得非常好,编写得非常好,但有一个例外值得一提。在手动滚动协议解析器时,我不会效仿它。相反,使用解析器生成器。我在这里写了一些关于在 Nginx 中使用解析器生成器 (Ragel) 的内容:

    http://www.evanmiller.org/nginx-modules-guide-advanced.html#parsing

    所有这些信息可能比您想要的更多,但希望您会发现其中的一些有用。

    【讨论】:

      【解决方案2】:

      是和不是。虽然他们都使用 epoll,但从技术上讲,他们都使用事件循环来处理请求。您可以在wikipedia 找到有关什么是事件循环以及如何使用它们的更多信息。

      查看libevent(由gevent 使用,通常比tornado 更快、更稳定)或libev 了解实现。

      【讨论】:

      • 你能不能说得更具体一点,我在哪里可以找到关于所有这些东西的更多细节,libevent 就足够了?
      • 这是一本由维护者撰写的关于 libevent 的好书:wangafu.net/~nickm/libevent-book
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 1970-01-01
      • 2019-01-29
      相关资源
      最近更新 更多