web-dev-qa-db-fra.com

HTTP persistant / keepalive avec la bibliothèque PHP Curl?

J'utilise une simple bibliothèque PHP pour ajouter des documents à un index SOLR, via HTTP.

Il y a 3 serveurs impliqués, actuellement:

  1. La boîte PHP exécutant le travail d'indexation
  2. Une boîte de base de données contenant les données en cours d'indexation
  3. La boîte solr.

À 80 documents/sec (sur 1 million de documents), je remarque un taux d'interruption anormalement élevé sur les interfaces réseau sur les boîtes PHP et solr (2000/sec; de plus, le les graphiques sont presque identiques - lorsque le taux d'interruption sur le PHP pic de boîte, il pointe également sur la boîte de Solr), mais beaucoup moins sur la boîte de base de données (300/sec). J'imagine c'est simplement parce que j'ouvre et réutilise une seule connexion au serveur de base de données, mais chaque requête Solr ouvre actuellement une nouvelle connexion HTTP via cURL, grâce à la façon dont la bibliothèque client Solr est écrite.

Donc, ma question est:

  1. Peut-on créer cURL pour ouvrir une session Keepalive?
  2. Que faut-il pour réutiliser une connexion? - est-ce aussi simple que de réutiliser la ressource de poignée cURL?
  3. Dois-je définir des options cURL spéciales? (par exemple, forcer HTTP 1.1?)
  4. Existe-t-il des problèmes avec les connexions keepalive cURL? Ce script s'exécute pendant des heures à la fois; pourrai-je utiliser une seule connexion ou devrai-je me reconnecter périodiquement?
58
Frank Farmer

cURL PHP ( curl_setopt ) dit:

CURLOPT_FORBID_REUSE - TRUE pour forcer la connexion à se fermer explicitement une fois le traitement terminé et à ne pas être regroupée pour être réutilisée.

Alors:

  1. Oui, en fait, il devrait réutiliser les connexions par défaut, tant que vous réutilisez le handle cURL.
  2. par défaut, cURL gère lui-même les connexions persistantes; si vous avez besoin d'en-têtes spéciaux, consultez CURLOPT_HTTPHEADER
  3. le serveur peut envoyer un délai d'attente (avec l'installation par défaut d'Apache, c'est 15 secondes ou 100 requêtes, selon la première éventualité) - mais cURL ouvrira simplement une autre connexion lorsque cela se produira.
53
Piskvor

Curl envoie l'en-tête keep-alive par défaut, mais:

  1. créer un contexte en utilisant curl_init() sans aucun paramètre.
  2. stocker le contexte dans une étendue où il survivra (pas une var locale)
  3. utilisez l'option CURLOPT_URL pour passer l'url au contexte
  4. exécuter la requête en utilisant curl_exec()
  5. ne ferme pas la connexion avec curl_close()

exemple très basique:

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);
21
Richard Keizer
  1. Sur le serveur auquel vous accédez, keep-alive doit être activé et le nombre maximal de requêtes keep-alive doit être raisonnable. Dans le cas d'Apache, reportez-vous à Apache docs .

  2. Vous devez réutiliser le même contexte cURL.

  3. Lors de la configuration du contexte cURL, activez keep-alive avec timeout dans l'en-tête:

    curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array(
        'Connection: Keep-Alive',
        'Keep-Alive: 300'
    ));
    
14
Oleg Barshay

Si vous ne vous souciez pas de la réponse de la demande, vous pouvez les faire de manière asynchrone, mais vous courez le risque de surcharger votre index SOLR. J'en doute cependant, SOLR est sacrément rapide.

Asynchrone PHP appels?

1
Brent