2009-06-09 10 views
52

Sto utilizzando una semplice libreria PHP per aggiungere documenti a un indice SOLR, tramite HTTP.HTTP persistente/keepalive con la libreria PHP Curl?

Ci sono 3 server coinvolti, attualmente:

  1. La casella di PHP che esegue il processo di indicizzazione
  2. Una scatola di database che contiene i dati che vengono indicizzati
  3. La scatola solr.

A 80 documenti/sec (su 1 milione di documenti), sto notando un tasso di interruzione insolitamente alto sulle interfacce di rete sulle scatole di PHP e Solr (2000/sec; per di più, i grafici sono quasi identico - quando il tasso di interruzione sui picchi di box PHP, si innesca anche sulla casella Solr), ma molto meno sul box del database (300/sec). Immagino che questo sia semplicemente perché apro e riuso una singola connessione al server del database, ma ogni singola richiesta Solr sta attualmente aprendo una nuova connessione HTTP tramite cURL, grazie al modo in cui è scritta la libreria del client Solr.

Quindi, la mia domanda è:

  1. può arricciare essere fatto per aprire una sessione keepalive?
  2. Cosa serve per riutilizzare una connessione? - è semplice come riutilizzare la risorsa handle cURL?
  3. Devo impostare le opzioni speciali CURL? (ad esempio, forza HTTP 1.1?)
  4. Esistono trucchi con connessioni keepalive cURL? Questo script viene eseguito per ore alla volta; sarò in grado di utilizzare una singola connessione o dovrò riconnettermi periodicamente?
+3

Beh io ho l'uso d dove stavamo analizzando un intero sito con molte pagine che richiedevano l'autenticazione e mantenevano una sessione in tutto il mondo. Utilizzando la risorsa di gestione iniziale è possibile continuare a eseguire comandi per ottenere pagine e mantenere la stessa sessione e connessione con il client. Utilizzando la riga di comando questo è durato per circa 20 minuti (per tutti i nostri requisiti di dati - quindi potrebbe durare più a lungo) senza bisogno di ricollegarsi. Ma non sono sicuro se questo è quello che stai chiedendo quindi è un commento e non una risposta :) –

+0

Un'altra nota, spesso ci sono opzioni che dovrai impostare in base a ciò che stai facendo e al server che sei collegamento a. Tutto questo è ben documentato qui: http://uk3.php.net/manual/en/function.curl-setopt.php –

+3

Questa parte delle FAQ è rilevante, anche se non eccessivamente dettagliata: http: //curl.haxx .se/docs/faq.html # Can_I_perform_multiple_requests –

risposta

49

documentazione cURL PHP (curl_setopt) dice:

CURLOPT_FORBID_REUSE - TRUE per forzare la connessione a chiudere esplicitamente quando ha finito il processo e non può essere riutilizzata.

Quindi:

  1. connessioni Sì, in realtà dovrebbe ri-utilizzare per impostazione predefinita, a patto che si ri-utilizzare la maniglia cURL.
  2. per impostazione predefinita, cURL gestisce le connessioni permanenti di per sé; se hai bisogno di intestazioni speciali, controlla CURLOPT_HTTPHEADER
  3. il server può inviare un timeout keep-alive (con l'installazione di Apache predefinita, è 15 secondi o 100 richieste, a seconda dell'evento che si verifica per primo) - ma cURL aprirà un'altra connessione quando ciò accade .
+1

Brillante! Ero così vicino a pubblicare la mia prima domanda StackOverflow. Questa soluzione ha funzionato per il nostro middleware a condizione che abbiamo aggiunto l'intestazione della richiesta 'Connection: close'. – renevanderark

1

Se non si cura della risposta della richiesta, è possibile eseguirli in modo asincrono, ma si rischia di sovraccaricare l'indice SOLR. Ne dubito, SOLR è dannatamente veloce.

Asynchronous PHP calls?

+0

Questo è certamente interessante, ma non risolve il problema del riutilizzo della connessione. In effetti, peggiorerebbe solo la mia connessione. –

13
  1. Sul server si accede keep-alive deve essere abilitato e massimo le richieste di keep-alive dovrebbero essere ragionevoli.Nel caso di Apache, fare riferimento a apache docs.

  2. È necessario riutilizzare lo stesso contesto cURL.

  3. Quando si configura il contesto cURL, abilitare keep-alive con timeout nell'intestazione:

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

Mi chiedo se CURL manda un header Keep-Alive per impostazione predefinita ... –

+2

Frank, ho appena riesaminato il mio codice e sembra essere attivo per impostazione predefinita. Non potrei fare male a impostarlo esplicitamente però. –

+1

@OlegBarshay sai se è necessario rimuovere 'curl_close ($ curlHandle);' per mantenere viva la conn. ? – zeflex

19

Curl invia l'intestazione keep-alive di default, ma:

  1. creare un contesto che utilizza curl_init() senza alcun parametro.
  2. negozio il contesto in un ambito in cui esso sopravviverà (non un var locale)
  3. uso CURLOPT_URL opzione per passare l'URL al contesto
  4. eseguire la richiesta utilizzando curl_exec()
  5. non si chiudono il collegamento con curl_close()

esempio molto semplice:

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

Devi anche impostare cookie prima della seconda chiamata, qualcosa come:' curl_setopt ($ context, CURLOPT_COOKIE, 'name = value') ; 'ad esempio per la mia richiesta è' curl_setopt ($ context, CURLOPT_COOKIE, 'PHPSESSID = bl392rgi8q664l7faat33hfta4'); ' –