La concurrence PHP utilise la concurrence curl pour réduire le temps d'accès au backend

不言
Libérer: 2023-03-23 11:24:02
original
2197 Les gens l'ont consulté

Le contenu partagé avec vous dans cet article concerne l'utilisation de la concurrence curl en PHP pour réduire le temps d'accès au back-end. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer


Tout d'abord, comprenons la fonction multi-thread curl en PHP :

# curl_multi_add_handle
# curl_multi_close
# curl_multi_exec
# curl_multi_getcontent
# curl_multi_info_read
# curl_multi_init
# curl_multi_remove_handle
# curl_multi_select
Copier après la connexion
De manière générale, lorsque l'on pense utiliser ces fonctions, le but doit évidemment être de demander plusieurs URL à la fois. en même temps, pas une seule requête en séquence, sinon il est préférable de boucler et d'ajuster curl_exec par vous-même.


Les étapes sont résumées comme suit :

Étape 1 : Appeler curl_multi_init
Étape 2 : Appeler curl_multi_add_handle dans une boucle
Il est à noter dans cette étape que le deuxième paramètre de curl_multi_add_handle est donné par Subhandle de curl_init.
Étape 3 : Continuez à appeler curl_multi_exec
Étape 4 : Appelez curl_multi_getcontent en boucle pour obtenir les résultats nécessaires
Étape 5 : Appelez curl_multi_remove_handle et appelez curl_close pour chaque descripteur de mot
Étape 6 : Appelez curl_multi_close

Voici un exemple simple trouvé en ligne L'auteur le qualifie de sale exemple (j'expliquerai pourquoi sale plus tard) :

/*
Here's a quick and dirty example for curl-multi from PHP, tested on PHP 5.0.0RC1 CLI / FreeBSD 5.2.1
*/

$connomains = array(
"http://www.cnn.com/",
"http://www.canada.com/",
"http://www.yahoo.com/"
);

$mh = curl_multi_init();

foreach ($connomains as $i => $url) {
     $conn[$i]=curl_init($url);
      curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
      curl_multi_add_handle ($mh,$conn[$i]);
}

do { $n=curl_multi_exec($mh,$active); } while ($active);

foreach ($connomains as $i => $url) {
      $res[$i]=curl_multi_getcontent($conn[$i]);
      curl_close($conn[$i]);
}

print_r($res);
Copier après la connexion


Le L'ensemble du processus d'utilisation est presque comme ça. Cependant, ce code simple a une faiblesse fatale, c'est-à-dire que dans la boucle do, il s'agit d'une boucle infinie pendant toute la demande d'URL, ce qui peut facilement amener le processeur à occuper 100 %.

Améliorons-le maintenant. Ici, nous devons utiliser une fonction curl_multi_select qui n'a presque aucune documentation. Bien que la bibliothèque curl de C ait des instructions pour la sélection, l'interface et l'utilisation en PHP sont en effet différentes de celles en C. .

Modifiez la section "faire" ci-dessus comme suit :
                                                                                                                                    
En ce qui concerne la valeur de retour de curl_multi_exec, il est jugé s'il y a encore des données. Lorsqu'il y a des données, curl_multi_exec sera appelé en continu. S'il n'y a pas de données pour le moment, il entrera dans l'étape de sélection. Une fois que de nouvelles données arriveront, elles pourront être réveillées pour continuer l'exécution. L’avantage ici est qu’il n’y a pas de consommation inutile de CPU.

  do {
                        $mrc = curl_multi_exec($mh,$active);
                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
                while ($active and $mrc == CURLM_OK) {
                        if (curl_multi_select($mh) != -1) {
                                do {
                                        $mrc = curl_multi_exec($mh, $active);
                                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
                        }
                }
Copier après la connexion
De plus : Il y a quelques détails que vous pouvez rencontrer parfois :


Contrôlez le délai d'attente de chaque requête, faites-le via curl_setopt avant curl_multi_add_handle :
curl_setopt($ch , CURLOPT_TIMEOUT, $ timeout);

Pour déterminer s'il a expiré ou s'il y a d'autres erreurs, utilisez : curl_error($conn[$i]);



<🎜 avant curl_multi_getcontent >Ici J'utilise simplement le sale exemple mentionné ci-dessus (c'est suffisant, et je n'ai pas trouvé d'utilisation du processeur à 100%).

Simuler la concurrence sur une certaine interface de "Kandian.com". La fonction est de lire des données et d'écrire des données dans memcache. Pour des raisons de confidentialité, les données et résultats pertinents ne seront pas publiés.

Simulé trois fois. La première fois, 10 threads demandés 1000 fois en même temps. La deuxième fois, 100 threads demandés 1000 fois en même temps. temps (c'est déjà assez pénible, je n'ose pas dans des décors à plus de 1000 multithreads).

Il semble que la concurrence de simulation multithread curl ait encore certaines limites.

De plus, je soupçonnais également qu'il pouvait y avoir une erreur importante dans les résultats en raison du retard multi-thread, et je l'ai découvert en comparant les données. Il n'y a pas beaucoup de différence dans le temps nécessaire à l'initialisation et à la définition. La différence réside dans la méthode get, donc cela peut être simplement éliminé ~~~

http ://log.dongsheng.org/2008/07/16/curl-multiple-handlers/

Habituellement, cURL en PHP exécute le blocage, ce qui signifie qu'après avoir créé une requête cURL, vous devez attendre qu'elle s'exécute. La requête suivante ne sera exécutée que lorsqu'elle réussit ou expire. La série de fonctions curl_multi_* permet un accès simultané réussi. La documentation PHP ne présente pas cette fonction en détail. :



源码打印?

$requests = array(&#39;http://www.baidu.com&#39;, &#39;http://www.google.com&#39;);  
$main    = curl_multi_init();  
$results = array();  
$errors  = array();  
$info = array();  
$count = count($requests);  
for($i = 0; $i < $count; $i++)   
{    
$handles[$i] = curl_init($requests[$i]);    
var_dump($requests[$i]);    
curl_setopt($handles[$i], CURLOPT_URL, $requests[$i]);    
curl_setopt($handles[$i], CURLOPT_RETURNTRANSFER, 1);    
curl_multi_add_handle($main, $handles[$i]);  
}  
$running = 0;   
do {    
curl_multi_exec($main, $running);  
}   
while($running > 0);   
for($i = 0; $i < $count; $i++)  
{  $results[] = curl_multi_getcontent($handles[$i]);    
$errors[]  = curl_error($handles[$i]);    
$info[]    = curl_getinfo($handles[$i]);    
curl_multi_remove_handle($main, $handles[$i]);  
}  
curl_multi_close($main);  
var_dump($results);  
var_dump($errors);  
var_dump($info);
Copier après la connexion


http://www.searchtb.com/2010/12/using-multicurl-to-improve-performance.html

前言:在我们平时的程序中难免出现同时访问几个接口的情况,平时我们用curl进行访问的时候,一般都是单个、顺序访问,假如有3个接口,每个接口耗时500毫秒那么我们三个接口就要花费1500毫秒了,这个问题太头疼了严重影响了页面访问速度,有没有可能并发访问来提高速度呢?今天就简单的说一下,利用curl并发来提高页面访问速度,希望大家多指导。1、老的curl访问方式以及耗时统计




源码打印?

<?php function curl_fetch($url, $timeout=3){       
$ch = curl_init();       
curl_setopt($ch, CURLOPT_URL, $url);       
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);       
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);       
$data = curl_exec($ch);       
$errno = curl_errno($ch);       
if ($errno>0) {           
$data = false;       
}       
curl_close($ch);       
return $data;   
}   
function microtime_float()   
{      
list($usec, $sec) = explode(" ", microtime());      
return ((float)$usec + (float)$sec);   
}   
$url_arr=array(        
"taobao"=>"http://www.taobao.com",        
"sohu"=>"http://www.sohu.com",        
"sina"=>"http://www.sina.com.cn",        
);    
$time_start = microtime_float();    
$data=array();    
foreach ($url_arr as $key=>$val)    
{        
$data[$key]=curl_fetch($val);    
}    
$time_end = microtime_float();    
$time = $time_end - $time_start;    
echo "耗时:{$time}";   
?>
Copier après la connexion

耗时:0.614秒
2、curl并发访问方式以及耗时统计




源码打印?

<?php   
function curl_multi_fetch($urlarr=array()){       
$result=$res=$ch=array();       
$nch = 0;       
$mh = curl_multi_init();       
foreach ($urlarr as $nk => $url) {           
$timeout=2;           
$ch[$nch] = curl_init();           
curl_setopt_array($ch[$nch], array(           
CURLOPT_URL => $url,           
CURLOPT_HEADER => false,           
CURLOPT_RETURNTRANSFER => true,           
CURLOPT_TIMEOUT => $timeout,           
));           
curl_multi_add_handle($mh, $ch[$nch]);           
++$nch;     }       
/* wait for performing request */      
do {           
$mrc = curl_multi_exec($mh, $running);       
} while (CURLM_CALL_MULTI_PERFORM == $mrc);         
while ($running && $mrc == CURLM_OK) {           
// wait for network           
if (curl_multi_select($mh, 0.5) > -1) {               
// pull in new data;               
do {                   
$mrc = curl_multi_exec($mh, $running);               
} while (CURLM_CALL_MULTI_PERFORM == $mrc);           
}       
}         
if ($mrc != CURLM_OK) {           
error_log("CURL Data Error");       
}         
/* get data */      
$nch = 0;       
foreach ($urlarr as $moudle=>$node) {           
if (($err = curl_error($ch[$nch])) == &#39;&#39;) {               
$res[$nch]=curl_multi_getcontent($ch[$nch]);             $result[$moudle]=$res[$nch];         }           
else          
{               
error_log("curl error");           
}           
curl_multi_remove_handle($mh,$ch[$nch]);           
curl_close($ch[$nch]);           
++$nch;       
}       
curl_multi_close($mh);       
return  $result;   
}   
$url_arr=array(        
"taobao"=>"http://www.taobao.com",        
"sohu"=>"http://www.sohu.com",        
"sina"=>"http://www.sina.com.cn",        
);   
function microtime_float()   
{      
list($usec, $sec) = explode(" ", microtime());      
return ((float)$usec + (float)$sec);   
}   
$time_start = microtime_float();   
$data=curl_multi_fetch($url_arr);   
$time_end = microtime_float();   
$time = $time_end - $time_start;   
echo "耗时:{$time}";   
?>
Copier après la connexion

耗时:0.316秒
帅气吧整个页面访问后端接口的时间节省了一半
3、curl相关参数
来自:http://cn2.php.net/manual/en/ref.curl.php
curl_close — Close a cURL session
curl_copy_handle — Copy a cURL handle along with all of its preferences
curl_errno — Return the last error number
curl_error — Return a string containing the last error for the current session
curl_exec — Perform a cURL session
curl_getinfo — Get information regarding a specific transfer
curl_init — Initialize a cURL session
curl_multi_add_handle — Add a normal cURL handle to a cURL multi handle
curl_multi_close — Close a set of cURL handles
curl_multi_exec — Run the sub-connections of the current cURL handle
curl_multi_getcontent — Return the content of a cURL handle if CURLOPT_RETURNTRANSFER is set
curl_multi_info_read — Get information about the current transfers
curl_multi_init — Returns a new cURL multi handle
curl_multi_remove_handle — Remove a multi handle from a set of cURL handles
curl_multi_select — Wait for activity on any curl_multi connection
curl_setopt_array — Set multiple options for a cURL transfer
curl_setopt — Set an option for a cURL transfer
curl_version — Gets cURL version information

前端开发中的性能那点事(三)php的opcode缓存

前端开发中的性能那点事(一)巧用xdebug

 

http://www.oschina.net/question/234345_42245

 相关推荐:

php并发之关于查询MySQL的示例(图)

PHP并发读写文件如何解决

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!