2009-06-09 19 views
52

Estoy usando una biblioteca PHP simple para agregar documentos a un índice SOLR, a través de HTTP.HTTP persistente/keepalive con la biblioteca PHP Curl?

Hay 3 servidores implicados, en la actualidad:

  1. El cuadro de PHP ejecutar el trabajo de indexación
  2. un cuadro de base de datos que contiene los datos que se indexa
  3. El cuadro de Solr.

A los 80 documentos/seg (de un total de 1 millón de documentos), estoy notando una inusualmente alta tasa de interrupción de las interfaces de red en las cajas de PHP y Solr (2000/seg, lo que es más, los gráficos casi son idéntico - cuando la tasa de interrupción en el cuadro de PHP aumenta, también aumenta en el cuadro de Solr), pero mucho menos en el cuadro de la base de datos (300/seg). Imagino que esto es simplemente porque abro y reutilizo una única conexión al servidor de la base de datos, pero cada solicitud Solr está abriendo una nueva conexión HTTP a través de cURL, gracias a la forma en que se escribe la biblioteca del cliente Solr.

Por lo tanto, mi pregunta es:

  1. se pueden enroscar hacerse para abrir una sesión de mantenimiento de conexión?
  2. ¿Qué se necesita para volver a utilizar una conexión? - ¿Es tan simple como reutilizar el recurso de control cURL?
  3. ¿Debo establecer alguna opción especial de CURSOR? (por ejemplo, forzar HTTP 1.1?)
  4. ¿Hay algún problema con las conexiones keepalive de cURL? Esta secuencia de comandos se ejecuta durante horas a la vez; ¿podré usar una sola conexión, o tendré que volver a conectarme periódicamente?
+3

Bueno tengo uso d en donde estábamos analizando un sitio completo con muchas páginas que requerían autenticación y mantenían una sesión en todas partes. Usando el recurso inicial del controlador puede continuar ejecutando comandos para obtener páginas y mantener la misma sesión y conexión con el cliente. Con la línea de comando, esto ha durado aproximadamente 20 minutos (para todos nuestros requisitos de datos, por lo que podría durar más) sin necesidad de volver a conectar. Pero no estoy seguro de si esto es lo que estás preguntando, por lo tanto, es un comentario y no una respuesta :) –

+0

Otra nota, a menudo hay opciones que tendrás que configurar dependiendo de lo que estés haciendo y del servidor que estés conectado a. Todo esto está bien documentado aquí: http://uk3.php.net/manual/en/function.curl-setopt.php –

+3

Esta parte de las preguntas frecuentes es relevante, aunque no muy detallada: http: //curl.haxx .se/docs/faq.html # Can_I_perform_multiple_requests –

Respuesta

49

documentación de PHP cURL (curl_setopt) dice:

CURLOPT_FORBID_REUSE - TRUE para forzar la conexión a cerrar explícitamente cuando se ha terminado de procesar, y que no se reserve para su reutilización.

Así:

  1. Sí, en realidad debería volver a utilizar las conexiones por defecto, siempre y cuando usted volver a utilizar el recurso CURL.
  2. de forma predeterminada, cURL maneja las conexiones persistentes por sí mismo; si necesita algunos encabezados especiales, marque CURLOPT_HTTPHEADER
  3. el servidor puede enviar un tiempo de espera de mantenimiento (con la instalación predeterminada de Apache, son 15 segundos o 100 solicitudes, lo que ocurra primero), pero cURL simplemente abrirá otra conexión cuando eso ocurra .
+1

¡Brillante! Estuve tan cerca de publicar mi primera pregunta de stackoverflow. Esta solución funcionó para nuestro middleware siempre que agreguemos el encabezado de solicitud 'Conexión: cerrar'. – renevanderark

1

Si no le interesa la respuesta de la solicitud, puede hacerlo de forma asíncrona, pero corre el riesgo de sobrecargar su índice SOLR. Sin embargo, lo dudo, SOLR es bastante rápido.

Asynchronous PHP calls?

+0

Eso es ciertamente interesante, pero no aborda la reutilización de la conexión en absoluto. De hecho, solo empeoraría mis problemas de conexión. –

13
  1. En el servidor que está accediendo keep-alive debe estar habilitado y el número máximo de solicitudes de mantenimiento de conexión debe ser razonable.En el caso de Apache, consulte el apache docs.

  2. Debe volver a utilizar el mismo contexto CURL.

  3. Al configurar el contexto cURL, permitirá mantener activa con el tiempo de espera en la cabecera:

    curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array(
        'Connection: Keep-Alive', 
        'Keep-Alive: 300' 
    )); 
    
+0

Me pregunto si CURL envía un encabezado Keep-Alive de forma predeterminada ... –

+2

Frank, acabo de volver a probar mi código y parece estar activado de forma predeterminada. Sin embargo, no podría doler establecerlo explícitamente. –

+1

@OlegBarshay, ¿sabes si necesitamos eliminar 'curl_close ($ curlHandle);' para mantener activa la conexión. ? – zeflex

19

Curl envía la cabecera de mantenimiento de conexión por defecto, pero:

  1. crear un contexto que usa curl_init() sin ningún parámetro.
  2. tienda el contexto en un ámbito en el que va a sobrevivir (no es una var)
  3. uso CURLOPT_URL opción para pasar el URL para el contexto
  4. ejecutar la solicitud utilizando curl_exec()
  5. no cierran la conexión con curl_close()

ejemplo muy básico:

function get($url) { 
    global $context; 
    curl_setopt($context, CURLOPT_URL, $url); 
    return curl_exec($context); 
} 

$context = curl_init(); 
//multiple calls to get() here 
curl_close($context); 
+0

También debe configurar la cookie antes de la segunda llamada, algo así como:' curl_setopt ($ context, CURLOPT_COOKIE, 'name = value') ; 'por ejemplo, para mi solicitud es' curl_setopt ($ context, CURLOPT_COOKIE, 'PHPSESSID = bl392rgi8q664l7faat33hfta4'); ' –