2010-02-19 2 views
5

Utilizzo una implementazione multipla cURL "a rotazione" (come this SO post, basata su this cURL code). Funziona bene per elaborare migliaia di URL utilizzando fino a 100 richieste allo stesso tempo, con 5 istanze dello script eseguite come daemon (si, lo so, questo dovrebbe essere scritto in C o qualcosa del genere).cURL timeout multi impiccagione/ignorato

Ecco il problema: dopo l'elaborazione di ~ 200.000 url (tra le 5 istanze) curl_multi_exec() sembra interromperle per tutte le istanze dello script. Ho provato a chiudere gli script, quindi a riavviarlo, e succede lo stesso (non dopo 200.000 url, ma al momento del riavvio), lo script si blocca chiamando curl_multi_exec().

Ho messo lo script in modalità 'single', elaborando un normale handle di cURL al momento, e funziona bene (ma non è proprio la velocità di cui ho bisogno). Il mio logging mi porta a sospettare che potrebbe aver colpito una patch di connessioni lente/problematiche (poiché ogni tanto sembra elaborare su URL e poi riattaccare), ma significherebbe che il mio CURLOPT_TIMEOUT viene ignorato per i singoli handle. O forse è solo qualcosa con l'esecuzione di molte richieste attraverso l'arricciatura.

Qualcuno ha mai sentito parlare di qualcosa del genere?

codice di esempio (sempre sulla base this):

//some logging shows it hangs right here, only looping a time or two 
//so the hang seems to be in the curl call 
while(($execrun = 
    curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM); 

//code to check for error or process whatever returned 

devo CURLOPT_TIMEOUT insieme a 120, ma nei casi in cui curl_multi_exec() torna finalmente alcuni dati, è dopo 10 minuti di attesa.

Ho un sacco di test/controllo ancora da fare, ma ho pensato che forse questo potrebbe suonare un campanello con qualcuno.

+0

Il blocco persistente durante il riavvio sembra un problema con le connessioni di limitazione del server remoto. –

+0

Usa 'shuffle()' prima dell'elaborazione, per la vittoria. –

risposta

8

Dopo molti test, credo di aver trovato ciò che sta causando questo particolare problema. Non sto dicendo che l'altra risposta sia errata, solo in questo caso non il problema che sto avendo.

Da quello che posso dire, curl_multi_exec() non viene restituito finché non viene risolto tutto il DNS (errore o esito positivo). Se ci sono un sacco di URL con domini cattive curl_multi_exec() non farvi ritorno per almeno:

(time it takes to get resolve error) * (number of urls with bad domain) 

Ecco qualcun altro who has discovered this:

Solo una nota sulla natura asincrona di multi funzioni di cURL: il Le ricerche DNS non sono (per quanto ne so oggi) asincrone. Quindi, se una ricerca DNS del tuo gruppo fallisce, anche tutto l'elenco di URL dopo quello fallisce. In realtà aggiorniamo il nostro hosts.conf (credo?) file sul nostro server ogni giorno per aggirare questo. Riceve gli indirizzi IP invece di cercarli. Credo che si stia lavorando, ma non sono sicuro che sia cambiato in cURL ancora.

Inoltre, il test mostra che cURL (almeno la mia versione) segue l'impostazione CURLOPT_CONNECTTIMEOUT. Naturalmente il primo passaggio di un ciclo multiplo potrebbe richiedere ancora molto tempo, poiché cURL attende che ogni URL venga risolto o scaduto.

6

Credo che il problema è releated a:

(62) CURLOPT_TIMEOUT non funziona correttamente con le normali interfacce multiple e multi_socket. La soluzione per le app è semplicemente rimuovere l'handle semplice una volta scaduto il tempo.

Consulta anche: http://curl.haxx.se/bug/view.cgi?id=2501457

Se questo è il caso si dovrebbe guardare la vostra arricciatura gestisce per i timeout e rimuoverli dal multi piscina.

+1

Esattamente quello che stavo cercando. Proverò del codice di prova e vedrò cosa succede. –