2010-11-27 79 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'); 
    ?> 

這真是快,甜內存使用