2010-09-24 18 views
19

En un script php, estoy haciendo un montón de solicitudes diferentes de cUrl GET (cien) a diferentes URL.Reutilizando el mismo controlador de curl. Gran aumento de rendimiento?

¿Reutilizar el mismo controlador curl_init mejorará el rendimiento o es insignificante en comparación con el tiempo de respuesta de las solicitudes cURL?

Lo estoy preguntando porque en la arquitectura actual no sería fácil mantener el mismo controlador de cUrl.

Gracias,

Benjamin

+0

¿Has visto en 'curl_multi_init'? –

+0

Sí, pero necesito hacer solicitudes de curl sincrónicas. – benjisail

Respuesta

16

Depende de si las direcciones están en mismos servidores o no. Si lo son, las solicitudes concurrentes al mismo servidor reutilizarán la conexión. ver CURLOPT_FORBID_REUSE.

Si las URL a veces están en el mismo servidor, debe ordenar las URL, ya que la caché de conexión predeterminada está limitada a diez o veinte conexiones.

Si están en servidores diferentes, no hay una ventaja de velocidad al usar el mismo controlador.

Con curl_multi_exec puede conectarse a diferentes servidores al mismo tiempo (paralelo). Incluso entonces necesita algunas colas para no usar miles de conexiones simultáneas.

+2

Esta respuesta es ambigua. No respondió explícitamente la pregunta del usuario: ¿está reutilizando el mismo controlador de curl ... mejora el rendimiento? Y la declaración "Si lo son, las solicitudes simultáneas al mismo servidor reutilizarán la conexión". <- esta frase se puede suponer utilizando el mismo controlador curl, o no utilizando el mismo curl. Si no es así, mejor explícitamente afirma que "Si lo son, las solicitudes simultáneas al mismo servidor reutilizarán la conexión, sin importar reutilizar el mismo controlador o no" –

2

Depende cuántas solicitudes se van a realizar - los gastos generales para el cierre de & reapertura cada uno es insignificante, pero cuando se hace un mil? Podría ser unos pocos segundos o más.

Creo que curl_multi_init sería el método más rápido.

Todo depende de la cantidad de solicitudes que necesite hacer.

+1

No puedo usar curl_multi_init porque mis solicitudes curl deben ser sincrónicas. Tendré cientos de solicitudes cada vez. – benjisail

1

mira esto también

 

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

No veo el sentido de su respuesta en relación con mi pregunta ... ¿Podría ser más preciso? – benjisail

+0

bueno, es un enfoque diferente al problema. si necesita tener toneladas de curl solicitudes GET, puede utilizar el HttpRequestPool de php que ha sido diseñado exactamente para este propósito: http://pecl.php.net/package/pecl_http – sathia

+0

'$ x = 0;' ¡¿Qué?! –

37

Crossposted desde Should I close cURL or not? porque creo que es relevante aquí también.

He intentado banqueo rizo con el uso de un nuevo identificador para cada solicitud y utilizando el mismo mango con el siguiente código:

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>'; 

y obtuvo los siguientes resultados:

Curl sin reutilización mango: 8.5690529346466
de Rizos y reutilización mango: 5,3703031539917

Así reutilizar el el mismo identificador proporciona un aumento sustancial en el rendimiento cuando se conecta al mismo servidor varias veces. He intentado conectar a diferentes servidores:

$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>'; 

y obtuvo el siguiente resultado:

Curl sin reutilización mango: 3.7672290802002
de Rizos y reutilización mango: 3.0146431922913

Aumento de rendimiento bastante considerable.

+0

por curiosidad, ¿qué está haciendo la llamada 'rand()' en el segunda prueba? Parece que eso podría introducir una diferencia sustancial entre los puntos de referencia que se comparan. – drobert

+0

@drobert Buen punto. No es necesario en la segunda prueba. Pero dado que la segunda prueba es de solo 10 iteraciones y estamos lidiando con tiempos en segundos, su impacto no es sustancial. – AlliterativeAlice

4

Tengo un escenario similar donde publico datos en un servidor. Está fragmentado en solicitudes de ~ 100 líneas, por lo que produce muchas solicitudes. En una evaluación comparativa, comparé dos enfoques para 12.614 líneas (se necesitan 127 solicitudes) más la autenticación y otra solicitud de orden y limpieza (129 solicitudes en total).

Las solicitudes pasan por una red a un servidor en el mismo país, no en el sitio. Están protegidos por TLS 1.2 (el saludo de mano también tendrá su efecto, pero dado que HTTPS se está convirtiendo cada vez más en una opción predeterminada, esto podría incluso hacer que sea más similar a su escenario).

Con reutilización cURL: uno $curlHandle que es curl_init() 'ed una vez, y entonces sólo modifica con CURLOPT_URL y 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) 

Sin reutilización cURL: uno curl_init por solicitud

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) 

No es el más grande de da tasets, pero se puede decir que todas las ejecuciones "reutilizadas" son más rápidas que todas las ejecuciones "init". Los tiempos promedio muestran una diferencia de casi 14 segundos.

Cuestiones relacionadas