6
votes

PHP CURL MULTI_EXEC Retard entre les demandes

Si j'exécute une fonction standard curl_multi_exec (exemple ci-dessous), je reçois toutes les poignées de courbure demandées à la fois. Je voudrais mettre un retard de 100 ms entre chaque demande, existe-t-il un moyen de le faire? (Rien trouvé sur Google & Stackoverflow Search)

J'ai essayé uleep () avant curl_multi_exec () qui ralentit le script mais ne pose pas chaque requête. P>

// array of curl handles & results
$curlies = array();
$result = array();
$mh = curl_multi_init();

// setup curl requests
for ($id = 0; $id <= 10; $id += 1) {
    $curlies[$id] = curl_init();
    curl_setopt($curlies[$id], CURLOPT_URL,            "http://google.com");
    curl_setopt($curlies[$id], CURLOPT_HEADER,         0);
    curl_setopt($curlies[$id], CURLOPT_RETURNTRANSFER, 1);
    curl_multi_add_handle($mh, $curlies[$id]);
}

// execute the handles
$running = null;
do {
    curl_multi_exec($mh, $running);
} while($running > 0);

// get content and remove handles
foreach($curlies as $id => $c) {
    $result[$id] = curl_multi_getcontent($c);
    curl_multi_remove_handle($mh, $c);
}

// all done
curl_multi_close($mh);


7 commentaires

Le support CURL de PHP n'offre pas ce type de fonctionnalité.


Toute autre méthode de non-curl? Cela répondrait également à ma question. Merci.


PHP n'est pas multithreadé du tout. Vous devez exécuter plusieurs copies du script en parallèle. Et chaque copie du script serait complètement indépendante des autres. Vous devez avoir une méthode de rachat à chaque script que la ou les URL devraient chercher


Je comprends que Curl Multi n'est qu'un seul fil qui attend que toutes les connexions se résolvent. Des solutions similaires avec un thread résoudront mon problème. Je ne veux pas de serveur DDO avec 1000 demandes à la fois, mais je ne veux pas non plus exécuter les demandes une à la fois (trop lente).


Toutes les URL sont-elles sur un seul site? Ou frappez-vous plusieurs sites? Si c'est multiple, appuyez sur un site dans chaque fil multi-thread et placez une pause de 100 ms sur l'ensemble du script. Cela ferait apparaître comme 1-hit-per-100ms sur chaque site, même si vous frappez 5 ou 10 sites en même temps.


Pas vraiment multithreadisé, si vous avez pcntl_fork () < / a> Vous pouvez Exécuter le code dans les processus enfants .


@MARC B Toutes les URL sont sur un seul site. Je suis en train de ping que ma propre API sur un autre serveur.


4 Réponses :


3
votes

Ne pense pas que tu peux. Si vous exécutez ceci à partir de la CLI, vous pouvez plutôt Fourchette votre script dans 10 processus, puis tirez des demandes de boucle régulières de chacun. Cela vous permettrait de contrôler le contrôle de la timing.


1 commentaires

Il a fonctionné à l'aide de ce script: blog.motane.lu/2009/01 / 02 / multithreading-in-php



4
votes

Oui, c'est possible. Si vous utilisez Bibliothèque parallèleCurl , vous pouvez également ajouter plus facilement votre délai de 100 ms avec USLEeP () code> , car vous pouvez faire une demande distincte à ajouter à la Télécharger la file d'attente.

for ($urls as $url) {
    $pcurl->startRequest($url);
    usleep(100000);
}


3 commentaires

Malheureusement, ça ne marche pas. La script est suspendue pour toujours et je ne suis pas le seul à signaler le problème: Github.com/petewarden/parallelcurl/issues


Bizarre. Peut-être a-t-il été mis à jour depuis que je le saisi dernier. J'utilise cette méthode dans 2 applications différentes en ce moment, et je n'ai pas de problèmes. Je vais jeter un coup d'œil à ma version ce soir et poster une mise à jour. Peut-être que cela a à voir avec une modification différente de ma copie que j'ai faite ...


Je confirme. Aucun problème avec cette méthode. +1. Forking ne peut pas être utilisé sur le Web. Mais Parallelcurl fonctionne sur le Web et la ligne de commande.



1
votes

php n'est pas une solution pour cela. Forking Le script ne va pas aider aussi. Dans les débuts oui, mais une fois que vous avez un peu plus de sites Web, vous devez saisir comme si vous vous retrouverez comme votre sévère très, très rouge. En termes de coûts et en termes de stabilité des scripts, vous devez reconsidérer en utilisant une autre idée.

Vous pouvez le faire avec Python facilement et en cas d'appels de temps réel non bloquants sur les points de terminaison API, vous devez utiliser des trucs comme socket.io + nœud.js ou juste node.js ou bien, hein ... lol

Si vous n'avez pas de temps ni que vous ne pouvez utiliser des choses comme ceci:

http://framework.zend.com/ Manuel / EN / ZENDX.CONSOLE.PROCESS.UNIX.OVERVIEW.HTML

Cela dépend tout de ce que vous essayez d'atteindre.


1 commentaires

Je suis d'accord avec la dernière sentance :) Je suis toujours le même serveur (API). Le serveur peut contenir les demandes mais je veux juste les reporter sans attendre la demande Prevoide de terminer.



0
votes

Vous pouvez essayer ceci:
Stockez un horodatage dans la base de données, ajoutez une poignée et appelez à curl_multi_exec .
Utilisez curlopt_progressfunction pour vérifier les horaires et ajouter plus de poignées lorsque vous en avez besoin.
ici Daniel Stenberg (Auteur de Curl et Libcurl) dit qu'il est possible d'ajouter plus de poignées après exécution curl_multi_exec .


0 commentaires