2010-11-27 81 views
3

我需要在PHP中使用cURL向请求API的cURL请求千个。我目前的计划是与curl_multi_()函数并行执行这些操作。基本上可以同时并行执行所有数千个cURL请求。打开数千个cURL手柄而不会遇到问题? (PHP)

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

如果我需要限制一次创建的cURL请求的数量,那么设置限制的最佳值是什么?

背景:我现在与Godaddy共享主机,它可以很好地处理cURL请求,尽管我没有用数千个并行请求测试它。在未来,我将在Rackspace Cloud Site,它可以处理适度的负载。

这大量的cURL请求是每年一次的事情,而不是日常网站操作的一部分。

回答

5

这听起来像是一个架构问题。为什么你需要同时提出数千个请求?这种类型的组件会做什么好事,或者你会偶然地拒绝DOS(拒绝服务)一些可怜的怀疑Web服务/ API?

假设你没有敲打单个远程服务器,你仍然需要担心你的本地盒子可以处理多少个连接。只有很多端口可以使用,而且它们的测量数量很少。如果你打算建立连接,那么达到这个限制并不难。任何过度使用apachebench进行负载测试的人都知道这一点。

对于这种事情PHP不是一个好工具 - 我是一个做90%PHP的人。没有线程,而且内存密集。如果你想要并行1000个PHP进程,你将需要多台机器。你的典型PHP过程将消耗大约10-20兆内存,除非你调整了它(可能在编译时)(0127)。如果你只有24或36个并行进程会怎么样?

这就是说,我可能会这样做,PHP可能会正常工作,如果遇到内存不足问题,你可以换一个部分,你需要两个或多或少的异步队列,以及一对处理它们的进程:

  • A “获取队列” - 需要获取的HTTP请求的工作队列。他们执行请求并将数据粘贴到处理队列中(请参阅下一个项目符号)。

  • 一个“处理队列”工作队列,可以通过任何HTTP响应包含。当队列被处理时,它可以将新项目添加到“获取队列”

  • 在并行运行在获取队列上的一些进程(或几十个)。并行性在这里很不错,因为网络有很多延迟。

  • 一些在“处理队列”上咀嚼的进程 - 目前还不清楚并行性会对此有所帮助。所有这些处理都是在本地进行的,也可能是一个简单的循环。

+0

你的观点,我应该重新考虑这种方法实际上真正的戒指。在某些方面,它不是我必须使用API​​。除了我自己之外,我会接受你的回答给那些从中受益的人。 – babonk 2010-11-27 07:10:58

0

确实没有足够的信息。每个连接将使用多少带宽?除非它的几个字节你会窒息大多数连接一次打开许多套接字。即使你的账户被封顶,你的1000套接口的想法也将变得无足轻重。为什么不能打开100个套接字并在完成时循环。这是非常快的

1

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

1

timdev建议的所有东西都包含在Zebra cURL 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'); 
    ?> 

这真是快,甜内存使用