13

我需要创建专门的 HTTP 服务器,为此我计划使用 epoll sycall,但我想利用多个处理器/内核,我无法提出架构解决方案。ATM 我的想法是:创建多个线程,使用自己的 epoll 描述符,主线程接受连接并将它们分布在线程 epoll 之间。但是有没有更好的解决方案?我可以阅读哪些关于高负载架构的书籍/文章/指南?我只看过C10K文章,但大多数示例链接都已失效 :( 并且仍然没有关于此主题的深入书籍 :(。

谢谢你的回答。

UPD:请具体一点,我需要材料和示例(nginx 不是示例,因为它太复杂并且有多个抽象层来支持多个系统)。

4

3 回答 3

14

检查libeventlibev源。它们具有高度可读性,并且已经是一个很好的基础设施。

此外,libev 的文档中有大量关于几种经过验证的真实策略的示例。即使您更喜欢直接写信给epoll(),这些示例也可以带来一些见解。

于 2011-01-14T03:19:36.727 回答
12

..我的想法是:使用自己的epoll描述符创建多个线程,主线程接受连接并将它们分配给线程epoll。

是的,这是目前最好的方法,这就是 Nginx 的做法。线程的数量可以根据负载和/或机器上的物理内核数量来增加或减少。

额外线程(多于物理内核的数量)和事件之间的权衡是延迟和吞吐量之一。线程改善了延迟,因为它们可以先发制人地执行,但由于上下文切换和线程创建/删除所产生的开销而以吞吐量为代价。事件提高了吞吐量,但缺点是长时间运行的代码会导致整个线程停止。

第二个最好的是 Apache2 如何使用阻塞线程的线程池来做到这一点。这里没有事件处理,因此实现更简单,池意味着不会不必要地创建和销毁线程,但它不能真正与实现良好的线程/异步混合(如您尝试实现的或 Nginx)竞争。

第三个最好的是单独的异步事件处理,如 Lighttpd 或 Node.js。好吧,如果您不在服务器中进行繁重的处理,这是第二好的。但如前所述,一个长时间运行的 while 循环会阻塞整个服务器。

于 2011-01-14T04:21:55.037 回答
-4

除非您有一个 TB 的上行链路并计划为单个服务器上的 10000 个同时连接提供服务,否则请忘记epoll. 这只是无缘无故的不可移植性;poll甚至select会做得一样好。请记住,当太比特上行链路等成为标准时,您的服务器也将足够快,您仍然不需要epoll

如果您只是提供静态内容,也请忘记线程并使用 Linuxsendfile系统调用。这也是非标准的,但至少它提供了巨大的实际性能优势。

另请注意,其他设计决策(尤其是过度复杂性)将更多地影响您的服务器可以处理多少负载。举个例子,看看朴素的单线程、单进程如何thttpd在静态内容上击败 Apache 和朋友——根据我的经验,甚至在传统的 cgi 动态内容上!

于 2011-01-14T05:00:12.430 回答