Lorsque vous utilisez la fonction Curl_Multi dans PHP, vous pouvez rencontrer une situation commune: pendant le processus de traitement parallèle multi-request, Curl_Multi_Close () peut interrompre la demande actuellement en cours. Ce problème provoque parfois une défaillance du programme pour répondre à toutes les demandes simultanées, donc des mesures appropriées sont nécessaires pour éviter ce problème. Cet article présentera comment gérer efficacement le problème de l'interruption Curl_Multi_Close pendant le processus de demande.
curl_multi_close () est une fonction fournie par l'extension Curl de PHP pour fermer plusieurs poignées Curl créées par Curl_Multi_Init () . Sa fonction est de libérer la ressource, mais si la fonction est appelée à l'avance pendant le processus de demande, il est possible d'interrompre la demande inachevée. Cela peut entraîner une perte de données ou des demandes incomplètes, ce qui affectera la stabilité et les performances du système.
Voici un exemple de demande Curl_Multi simple:
<?php
// initialisation curl_multi Poignée
$mh = curl_multi_init();
// Créer plusieurs cURL Poignée
$ch1 = curl_init("http://gitbox.net/api/data1");
$ch2 = curl_init("http://gitbox.net/api/data2");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// Mettre chacun cURL Poignée添加到 multi Poignée中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Effectuez toutes les demandes
$running = null;
do {
$mrc = curl_multi_exec($mh, $running);
} while ($running > 0);
// Obtenez les données renvoyées
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
// fermeture cURL Poignée
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
// fermeture multi Poignée
curl_multi_close($mh);
?>
Dans cet exemple, nous ajoutons plusieurs poignées Curl à la poignée multiple $ mh via curl_multi_add_handle () et exécutons toutes les demandes en parallèle via curl_multi_exec () . Enfin, nous fermons le multi-mains via Curl_Multi_Remove_Handle () et Curl_Multi_Close () .
Le problème se produit lorsque curl_multi_close () est appelé, ce qui peut fermer plusieurs poignées à l'avance, ce qui entraîne l'interruption de la demande à mi-chemin. Si une interruption se produit lorsque toutes les demandes n'ont pas été terminées, la demande inachevée ne pourra pas obtenir de données de réponse ou de retour des résultats.
Pour s'assurer que curl_multi_close () n'interrompt pas la demande, les méthodes suivantes peuvent être utilisées:
La solution la plus courante est de s'assurer que toutes les demandes ont été remplies, puis d'appeler Curl_Multi_Close () . Vous pouvez utiliser la valeur de retour de curl_multi_exec () pour déterminer si toutes les demandes ont été remplies. Lorsque la valeur de la variable d'exécution est de 0, cela signifie que toutes les demandes ont été remplies. Ce n'est qu'alors que curl_multi_close () appelé.
Le code modifié est le suivant:
<?php
// initialisation curl_multi Poignée
$mh = curl_multi_init();
// Créer plusieurs cURL Poignée
$ch1 = curl_init("http://gitbox.net/api/data1");
$ch2 = curl_init("http://gitbox.net/api/data2");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// Mettre chacun cURL Poignée添加到 multi Poignée中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Effectuez toutes les demandes
$running = null;
do {
$mrc = curl_multi_exec($mh, $running);
// Un petit retard peut être ajouté ici pour ralentir CPU Taux d'utilisation
usleep(100);
} while ($running > 0);
// Obtenez les données renvoyées
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
// fermeture cURL Poignée
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
// fermeture multi Poignée
curl_multi_close($mh);
?>
La demande est exécutée en permanence via une boucle à faire jusqu'à ce que la course soit 0, date à laquelle toutes les demandes ont été remplies, et Curl_Multi_Close () peut être appelée en toute sécurité.
Parfois, même si toutes les demandes semblent avoir été remplies, elles peuvent être interrompues en raison de problèmes tels que les défaillances du réseau. Pour le moment, vous pouvez envisager de réessayer lorsque la demande échoue.
<?php
// Définissez le nombre maximum de temps de réessayer
$maxRetries = 3;
function performRequest($ch, $maxRetries) {
$retryCount = 0;
$response = null;
while ($retryCount < $maxRetries) {
$response = curl_exec($ch);
if ($response !== false) {
break;
}
$retryCount++;
usleep(500000); // Attendez un moment avant de réessayer
}
return $response;
}
// initialisation curl_multi Poignée
$mh = curl_multi_init();
// Créer plusieurs cURL Poignée
$ch1 = curl_init("http://gitbox.net/api/data1");
$ch2 = curl_init("http://gitbox.net/api/data2");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// Mettre chacun cURL Poignée添加到 multi Poignée中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Effectuez toutes les demandes
$running = null;
do {
$mrc = curl_multi_exec($mh, $running);
} while ($running > 0);
// Obtenez les données renvoyées,Essayer à nouveau
$response1 = performRequest($ch1, $maxRetries);
$response2 = performRequest($ch2, $maxRetries);
// fermeture cURL Poignée
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
// fermeture multi Poignée
curl_multi_close($mh);
?>
Dans le code ci-dessus, la fonction PerformRequest () essaie de réessayer lorsque la demande échoue jusqu'à ce que le nombre maximum de tentatives soit atteinte. Cela peut éviter efficacement les interruptions de demande en raison de problèmes de réseau.
curl_multi_select () peut aider les programmes PHP à gérer plusieurs demandes plus efficacement, en évitant d'appeler curl_multi_exec () dans chaque boucle. Il continuera d'exécuter la demande lorsque certaines conditions seront remplies, ce qui peut économiser des ressources système.
<?php
// initialisation curl_multi Poignée
$mh = curl_multi_init();
// Créer plusieurs cURL Poignée
$ch1 = curl_init("http://gitbox.net/api/data1");
$ch2 = curl_init("http://gitbox.net/api/data2");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// Mettre chacun cURL Poignée添加到 multi Poignée中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Effectuez toutes les demandes
$running = null;
do {
curl_multi_select($mh);
$mrc = curl_multi_exec($mh, $running);
} while ($running > 0);
// Obtenez les données renvoyées
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
// fermeture cURL Poignée
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
// fermeture multi Poignée
curl_multi_close($mh);
?>
curl_multi_select () peut attendre lorsqu'il n'y a pas de données disponibles, évitant ainsi l'utilisation inutile du processeur. C'est une manière plus efficace, surtout quand il y a beaucoup de demandes.