代码之家  ›  专栏  ›  技术社区  ›  Ben G

打开数千个卷曲手柄而不遇到问题?(PHP)

  •  3
  • Ben G  · 技术社区  · 15 年前

    我需要在PHP中使用curl 对API的curl请求。我目前的计划是与curl_multi_u()函数并行执行这些操作。基本上是同时并行执行所有数千个curl请求。

    我听说打开太多的句柄会遇到内存问题,这会导致致命的错误。如何才能避免这种情况,并使我的URL请求尽可能快?

    如果我需要限制一次要发出的curl请求的数量,那么将限制设置为什么样的好?

    背景:我现在正在和Godaddy共享主机,这对curl请求很好,尽管我还没有用数千个并行请求测试过它。以后我会在 Rackspace Cloud Site 它能承受适度的负荷。

    这种巨大的curl请求是每年一次,而不是日常站点操作的一部分。

    4 回复  |  直到 11 年前
        1
  •  5
  •   timdev    15 年前

    这听起来像是一个体系结构问题。为什么你需要同时提出数千个请求?这种Parellism会有什么好处吗,或者你只是无意中做了一些错误的DoS(拒绝服务),怀疑Web服务/API?

    假设您不是在敲打单个远程服务器,您仍然需要担心本地设备可以处理多少连接。只有这么多的端口可以使用传出端口,它们的测量值是以低数万计的。如果你想打开连接,就不难达到这个极限。任何使用Apachebench进行过载测试的人都知道这一点。

    对于这种事情,PHP不是一个很好的工具——我是一个90%使用PHP的人。没有线程,而且内存很密集。如果您希望1000个PHP进程并行,则需要多台机器。您典型的PHP进程将消耗大约10-20兆内存,除非您调优它(可能在编译时)。

    你说这种情况一年发生一次。这让我觉得可能没有必要这么做。如果你只有24或36个并行进程呢?

    也就是说,我可能会这样做。PHP可能会很好地工作,如果遇到内存效率低下的问题,您可以只交换一部分。您需要两个或更多或更少的异步队列,以及一对处理它们的进程:

    • “获取队列”—需要生成的HTTP请求的工作队列。它们执行请求并将数据粘贴到处理队列中(参见下一项)。

    • “处理队列”工作队列,通过HTTP响应包含的任何内容工作。正如处理队列一样,它可以将新项目添加到“提取队列”

    • 在获取队列上并行运行的一些进程(或几十个)。并行性在这里是很好的,因为由于网络的原因,您有太多的延迟。

    • 一些处理“处理队列”的过程——不清楚并行性在这里有什么帮助。所有这些处理都在本地进行,可能是一个简单的循环。

        2
  •  1
  •   SilentAssassin    13 年前

    退房 Rolling Curl . 我用它从多个网页中提取链接和网页内容。我不知道这在服务器上如何工作,因为我只在本地机器上有经验。

        3
  •  1
  •   Arron    12 年前

    Timdev提出的所有建议都用斑马卷发包裹起来了。 https://github.com/stefangabos/Zebra_cURL . 您可以传递一个URL数组,它会将一些(默认值为10)并行排队,然后调用它们并将结果对象传递到回调中。从Github文档:

        <?php
            function callback($result) {
                // remember, the "body" property of $result is run through
                // "htmlentities()", so you may need to "html_entity_decode" it
                // show everything
                print_r('<pre>');
                print_r($result->info);
            }
            require 'path/to/Zebra_cURL.php';
            // instantiate the Zebra_cURL class
            $curl = new Zebra_cURL();
            // cache results 60 seconds
            $curl->cache('cache', 60);
            // get RSS feeds of some popular tech websites
            $curl->get(array(
                'http://rss1.smashingmagazine.com/feed/',
                'http://allthingsd.com/feed/',
                'http://feeds.feedburner.com/nettuts',
                'http://www.webmonkey.com/feed/',
                'http://feeds.feedburner.com/alistapart/main',
            ), 'callback');
        ?>
    

    它的内存使用速度非常快而且很好

        4
  •  0
  •   joe    15 年前

    没有足够的信息。每个连接将使用多少带宽?除非它只有几个字节,否则您将阻塞大多数连接,同时打开许多套接字。即使你的账户被封顶了,你的1000个插座的想法也会变得毫无意义。为什么你不能打开100个插座,一个接一个地循环呢?这个很快