“epoll”是Tornadoweb(或Nginx)如此之快的重要原因吗?

Tornadoweb和Nginx是目前stream行的Web服务器,许多基准testing表明它们在某些情况下比Apache有更好的性能。 所以我的问题是:

epoll”是使他们如此之快的最重要的原因吗? 如果我想写一个好的套接字服务器,我可以从中学到什么?

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

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

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

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

最后,如果您需要一个很好的参考资料,请参阅W. Richard Stevens等人的“UNIX网络编程”。 人:

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,它只是一个更有效的选择版本。 如果有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的代码库组织得非常好,写得很好,除了一个例外。 当谈到协议解析器的手动操作时,我不会效仿它; 相反,使用解析器生成器。 我已经写了一些关于在这里使用一个解析器生成器(Ragel)与Nginx的东西:

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

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

是和不是。 虽然他们都使用epoll,但在技术上他们都使用事件循环来处理请求。 你可以找到更多关于什么事件循环以及如何在维基百科中使用的信息。

查看libevent (由gevent使用 ,通常比龙卷风更快更稳定)或Libev来实现。