2010-09-24 11 views
19

In uno script php sto facendo un sacco di richieste di GET cUrl diverse (un centinaio) a URL diversi.Riutilizzo della stessa maniglia di arricciatura. Grandi prestazioni aumentano?

Il riutilizzo dello stesso handle di curl da curl_init migliorerà le prestazioni o è un confronto trascurabile con il tempo di risposta delle richieste cURL?

Lo sto chiedendo perché nell'architettura attuale non sarebbe facile mantenere lo stesso handle di cUrl.

Grazie,

Benjamin

+0

Hai esaminato 'curl_multi_init'? –

+0

Sì, ma ho bisogno di fare richieste di ricciolo sincrono. – benjisail

risposta

16

Dipende se gli URL sono sullo stesso server o meno. Se lo sono, le richieste simultanee allo stesso server riutilizzeranno la connessione. vedi CURLOPT_FORBID_REUSE.

Se gli URL sono a volte sullo stesso server, è necessario ordinare gli URL poiché la cache di connessione predefinita è limitata a dieci o venti connessioni.

Se si trovano su server diversi, non vi è alcun vantaggio di velocità nell'utilizzo dello stesso handle.

Con curl_multi_exec è possibile connettersi a server diversi contemporaneamente (in parallelo). Anche in questo caso è necessario un po 'di coda per non utilizzare migliaia di connessioni simultanee.

+2

Questa risposta è ambigua. Non ha risposto esplicitamente alla domanda dell'utente - Sta riutilizzando lo stesso handle di ricciolo ... migliorare le prestazioni? E l'affermazione "Se lo sono, le richieste simultanee allo stesso server riutilizzeranno la connessione". <- Questa frase può essere considerata usando lo stesso handle di curl, o non usando lo stesso curl. Se non lo è, afferma esplicitamente che "Se lo sono, le richieste simultanee allo stesso server riutilizzeranno la connessione, non importa riutilizzare lo stesso handle di arricciatura o no" –

2

Dipende quante richieste si farà - le spese generali per la chiusura & riapertura ognuno è trascurabile, ma quando si fa un migliaio? Potrebbe essere qualche secondo o più.

Credo che curl_multi_init sarebbe il metodo più veloce.

Il tutto dipende da quante richieste è necessario eseguire.

+1

Non posso usare curl_multi_init perché le mie richieste di arricciatura devono essere sincrone. Avrò un centinaio di richieste ogni volta. – benjisail

1

controllo questo troppo

 

try { 
    $pool = new HttpRequestPool(
     new HttpRequest($q1), 
     new HttpRequest($qn) 
    ); 
    $pool->send(); 

    foreach($pool as $request) { 

     $out[] = $request->getResponseBody(); 

    } 
} catch (HttpException $e) { 
    echo $e; 
} 


+0

Non vedo il punto della tua risposta in relazione alla mia domanda ... Potresti essere più preciso? – benjisail

+0

beh, è ​​un approccio diverso al problema. se hai bisogno di avere tonnellate di richieste GET curl, puoi usare HttpRequestPool di php che è stato progettato esattamente per questo scopo: http://pecl.php.net/package/pecl_http – sathia

+0

'$ x = 0;' Che cosa?! –

37

Crossposted from Should I close cURL or not? perché penso che sia rilevante anche qui.

Ho provato a tenere in panchina ricciolo con l'utilizzo di una nuova maniglia per ogni richiesta e utilizzando lo stesso handle con il seguente codice:

ob_start(); //Trying to avoid setting as many curl options as possible 
$start_time = microtime(true); 
for ($i = 0; $i < 100; ++$i) { 
    $rand = rand(); 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $rand); 
    curl_exec($ch); 
    curl_close($ch); 
} 
$end_time = microtime(true); 
ob_end_clean(); 
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>'; 

ob_start(); //Trying to avoid setting as many curl options as possible 
$start_time = microtime(true); 
$ch = curl_init(); 
for ($i = 0; $i < 100; ++$i) { 
    $rand = rand(); 
    curl_setopt($ch, CURLOPT_URL, "http://www.google.com/?rand=" . $rand); 
    curl_exec($ch); 
} 
curl_close($ch); 
$end_time = microtime(true); 
ob_end_clean(); 
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>'; 

e ottenuto i seguenti risultati:

Curl senza manico riuso: 8,5690529346466
Curl con manico riuso: 5,3703031539917

Così il riutilizzo lo stesso handle fornisce in realtà un aumento sostanziale delle prestazioni quando ci si connette allo stesso server più volte. Ho provato il collegamento a server diversi:

$url_arr = array(
    'http://www.google.com/', 
    'http://www.bing.com/', 
    'http://www.yahoo.com/', 
    'http://www.slashdot.org/', 
    'http://www.stackoverflow.com/', 
    'http://github.com/', 
    'http://www.harvard.edu/', 
    'http://www.gamefaqs.com/', 
    'http://www.mangaupdates.com/', 
    'http://www.cnn.com/' 
); 
ob_start(); //Trying to avoid setting as many curl options as possible 
$start_time = microtime(true); 
foreach ($url_arr as $url) { 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_exec($ch); 
    curl_close($ch); 
} 
$end_time = microtime(true); 
ob_end_clean(); 
echo 'Curl without handle reuse: ' . ($end_time - $start_time) . '<br>'; 

ob_start(); //Trying to avoid setting as many curl options as possible 
$start_time = microtime(true); 
$ch = curl_init(); 
foreach ($url_arr as $url) { 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_exec($ch); 
} 
curl_close($ch); 
$end_time = microtime(true); 
ob_end_clean(); 
echo 'Curl with handle reuse: ' . ($end_time - $start_time) . '<br>'; 

e ottenuto il seguente risultato:

Curl senza manico riuso: 3,7672290802002
Curl con manico riutilizzo: 3.0146431922913

Ancora piuttosto un aumento sostanziale delle prestazioni.

+0

per curiosità, qual è la chiamata 'rand()' nel secondo test? Sembra che potrebbe introdurre una differenza sostanziale tra i benchmark confrontati. – drobert

+0

@drobert Buon punto. Non è necessario nel secondo test. Ma dal momento che il secondo test ha solo 10 iterazioni e abbiamo a che fare con tempi nei secondi, il suo impatto non è sostanziale. – AlliterativeAlice

4

Ho uno scenario simile in cui inserisco i dati su un server. È suddiviso in richieste di ~ 100 righe, quindi produce molte richieste. In un benchmark ho confrontato due approcci per 12.614 linee (127 richieste necessarie) più l'autenticazione e un'altra richiesta di manutenzione (129 richieste totali).

Le richieste passano su una rete verso un server nello stesso paese, non sul posto. Sono garantiti da TLS 1.2 (anche l'handshake avrà il suo pedaggio, ma dato che HTTPS sta diventando sempre più una scelta predefinita, questo potrebbe persino renderlo più simile al tuo scenario).

Con il riutilizzo cURL: uno $curlHandle che è curl_init() 'ed una volta, e poi modificato solo con CURLOPT_URL e CURLOPT_POSTFIELDS

Run 1: ~42.92s 
Run 3: ~41.52s 
Run 4: ~53.17s 
Run 5: ~53.93s 
Run 6: ~55.51s 
Run 11: ~53.59s 
Run 12: ~53.76s 
Avg: 50,63s/Std.Dev: 5,8s 
TCP-Conversations/SSL Handshakes: 5 (Wireshark) 

Senza riutilizzo cURL: una curl_init per richiesta

Run 2: ~57.67s 
Run 7: ~62.13s 
Run 8: ~71.59s 
Run 9: ~70.70s 
Run 10: ~59.12s 
Avg: 64,24s/Std. Dev: 6,5s 
TCP-Conversations/SSL Handshakes: 129 (Wireshark) 

Non è il più grande di da attività, ma si può dire che tutte le esecuzioni "riutilizzate" sono più veloci di tutte le esecuzioni "init". I tempi medi mostrano una differenza di quasi 14 secondi.

Problemi correlati