【问题标题】:serving large file using select, epoll or kqueue使用 select、epoll 或 kqueue 提供大文件
【发布时间】:2011-09-03 05:19:47
【问题描述】:

Nginx 使用 epoll 或其他多路复用技术 (select) 来处理多个客户端,即它不像 apache 那样为每个请求生成一个新线程。

我尝试使用 select 在我自己的测试程序中复制相同的内容。我可以通过创建一个非阻塞套接字并使用 select 来决定要服务哪个客户端来接受来自多个客户端的连接。我的程序会简单地将他们的数据回显给他们。它适用于小数据传输(每个客户端一些字节)

当我需要通过与客户端的连接发送大文件时,就会出现此问题。由于我只有一个线程为所有客户端提供服务,直到我完成读取文件并将其写入套接字时,我无法继续为其他客户端提供服务。

这个问题是否有已知的解决方案,或者最好为每个这样的请求创建一个线程?

【问题讨论】:

    标签: select nginx epoll kqueue


    【解决方案1】:

    使用 select 时,您不应一次发送整个文件。如果你例如正在使用 sendfile 执行此操作,它将阻塞,直到整个文件被发送。而是使用一个小缓冲区,并一次向每个客户端发送少量数据。然后使用 select 来确定套接字何时再次准备好写入并发送更多信息,直到所有数据都发送完毕。这将允许您并行处理多个客户端。

    【讨论】:

      【解决方案2】:

      最简单的方法是为每个请求创建一个线程,但它肯定不是最可扩展的方法。我认为目前基本上所有的高性能 Web 服务器都使用各种基于 epoll (Linux)、kqueue (BSD) 或 IOCP (Windows) 之类的异步方法。

      由于您没有提供有关性能要求的任何信息,并且由于所有非线程方法都需要重组您的应用程序以使用这些通常很复杂的异步技术(如 C10K article 和从那里找到的其他技术中所述) ,目前最好的办法就是使用线程方法。

      如果您需要更多,请更新您对性能和其他相关数据的具体要求。

      【讨论】:

        【解决方案3】:

        对于背景,这可能对阅读 http://www.kegel.com/c10k.html 有用

        【讨论】:

          【解决方案4】:

          我认为您正在使用回调来处理单个连接。这不是它的设计方式。您的回调必须处理您计划服务的任何数千个连接,即从您作为参数获得的文件描述符的数量,您必须知道(通过读取全局变量)如何处理该客户端,要么读取( ) 或 send() 或 ... 随便

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-09
            • 2016-04-06
            • 2013-06-27
            • 1970-01-01
            • 2012-11-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多