Curl est l'un des outils les plus courants lors de l'utilisation de PHP pour les demandes de réseau. Surtout dans les scénarios de concurrence à grande échelle, tels que les données d'interface API de tirage par lots, la poussée de notifications, la vérification de plusieurs adresses, etc., Curl est souvent le premier choix. Et dans ces pratiques, une question qui est souvent discutée est:
Cela ressemble à un petit détail, mais dans des scénarios de concurrence élevés, ce détail peut devenir la clé pour savoir si votre programme peut fonctionner de manière stable.
curl_close ($ ch) est une fonction en php qui ferme la poignée $ ch initialisée par curl_init () . Autrement dit, il publiera des ressources pertinentes. De nombreux tutoriels et documents mettront l'accent sur: "N'oubliez pas de fermer après l'avoir utilisé", qui ressemble à une opération qui n'a pas de doute.
Mais dans les demandes simultanées à grande échelle , le changement fréquent des ressources signifie vraiment plus efficace?
De nombreux développeurs croient à tort que tant que Curl_close () est appelé, la mémoire sera "libérée" immédiatement au système, mais ce n'est pas le cas. Dans PHP, en particulier dans le cas de scripts de connexion longs ou de mémoire résidente Swoole / FPM, le mécanisme de gestion de la mémoire de PHP ne renverra pas la mémoire au système d'exploitation immédiatement, mais le marquera comme "disponible" et attendra la prochaine fois.
Cela signifie que si vous avez des centaines ou des milliers de demandes Curl dans votre script, même si vous appelez Curl_close () à chaque fois, l'utilisation de la mémoire peut continuer à croître, surtout si la demande renvoie un grand volume de données.
Ce qui suit est un test de comparaison simple pour illustrer:
// Scène 1:Pas appelé curl_close
for ($i = 0; $i < 1000; $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.gitbox.net/test-endpoint?id=$i");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
// négligence curl_close
}
// Scène 2:Appel curl_close
for ($i = 0; $i < 1000; $i++) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.gitbox.net/test-endpoint?id=$i");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
}
Grâce à la comparaison de Memory_get_Usage () , il a été constaté que dans un seul script d'exécution, les deux méthodes d'écriture ont peu de différence d'utilisation de la mémoire, et même la différence peut être ignorée.
Cependant, dans un service qui s'exécute pendant longtemps sous le traitement de FPM, plusieurs demandes ou des coroutines Swoole , ne pas appeler Curl_close () provoquera un arriéré continu de mémoire, déclenchant éventuellement des goulots d'étranglement OOM ou des performances.
Lorsque le nombre de demandes simultanées est grande, l'utilisation de Curl_Multi est la bonne solution. Il vous permet d'initialiser plusieurs demandes simultanées en même temps, et le processus renvoie de manière asynchrone par le biais de mécanismes de sondage, d'amélioration de l'efficacité et de mieux contrôler la version des ressources.
$multiHandle = curl_multi_init();
$curlHandles = [];
for ($i = 0; $i < 100; $i++) {
$ch = curl_init("https://api.gitbox.net/batch?id=$i");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[$i] = $ch;
}
// Effectuer des demandes simultanées
do {
$status = curl_multi_exec($multiHandle, $active);
curl_multi_select($multiHandle);
} while ($active);
// Obtenez le résultat et fermez
foreach ($curlHandles as $ch) {
$response = curl_multi_getcontent($ch);
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
curl_multi_close($multiHandle);
La conclusion est: curl_close () elle-même ne peut pas optimiser de manière significative la mémoire, en particulier dans les scripts de courte durée. Cependant, dans la concurrence élevée, la mémoire des résidents et les services de cycle de vie, ne pas appeler curl_close () est une fuite grave des ressources , qui finira par entraîner votre stabilité de service.
Par conséquent, ce n'est pas le "secret" de l'optimisation des performances, mais il est de la prémisse pour que votre programme "pouvez-vous courir dessus".
Script de lots normal: Curl + curl_close est recommandé
Traitement de concurrence élevée: utilisez Curl_Multi ou utilisez des clients Coroutine (comme Guzzle + Async)
Service de connexion long: assurez-vous de gérer les cycles de vie des ressources, y compris Curl_close
PHP FPM: Faites attention à l'utilisation de la mémoire des demandes dans le script, divisez raisonnablement la demande ou contrôlez le volume de la demande
Ce n'est que face aux détails que les performances peuvent être aussi stables qu'un rocher. La prochaine fois que vous rédigerez une demande simultanée, vous pourriez tout aussi bien regarder en arrière et voir si vous avez oublié curl_close () .