Accélérer vos scripts php grâce au multithreading
Ecrit par Maxime le Jeudi 2 septembre 2010 à 13:43 - Catégorie Scripts PHP
Lecteur de SeoBlackOut, Tiger m’a fait le plaisir de publier ce premier article qui je l’espère vous plaira. Nous avons mis en place dans ma boite qui crée des boutiques en ligne ce script qui permet de multithreader des scripts php.
Imaginez le cas suivant : Vous souhaitez créer un script qui extrait des données du web. Si vous êtes très BlackHat ce sera pour extraire des digg-likes et des blogs à spammer, ou comme chez Vaisonet ce sera plutôt un script pour faire des relevés de prix sur les boutiques en ligne des concurrents de vos clients … C’est toujours plus sympathique que de le faire à main.
Dans tous les cas, vous ne voulez par faire quelque chose d’agressif et vous temporisez le tout. Vous avez donc certainement quelque chose comme cela :
$sites = array('www.siteA.fr', 'www.siteB.fr', 'www.siteC.fr', ) foreach($sites as $site) { //Votre fonction d'extraction extraction($site); //La tempo pour passer sous les radars sleep(15); }
Si vous voulez accélérer les choses, le seul moyen est de lancer toutes les extractions en parallèle. C’est facile à faire avec peu de paramètre, mais remplacez 3 sites exemples par 30 à faire tous les jours, c’est vite pénible !
L’idée est donc d’exécuter chaque élément de la boucle foreach dans un thread distinct en même temps que les autres.
Mauvaise nouvelle, php ne sait pas vraiment faire cela, il faut utiliser autre chose. De nombreux langages le permettent : C, C++, Java, etc … J’ai choisi Python. C’est un langage qui n’est pas compilé, rapide à coder et vous le verrez facile à comprendre.
Mais je vois déjà une objection pointer à l’horizon : pourquoi ne pas tout coder en Python ? Ce serait clairement la solution la plus pertinente techniquement, je suis parfaitement d’accord. Mais dans les faits, les cordonniers sont les plus mal chaussés : on traine de vieux bouts de code php issu d’une ancienne application web, ou on fait des extractions plus complexe en Perl avec Talend par exemple.
Et oui, avec le script qui arrive, vous pourrez aussi multithreader des scripts Perl !
Bref, cet outil vous permettra de recycler vos vieux bouts de code
Préalable sur Python
Il vous faut Python 3 installé sur votre poste : http://www.python.org/
Python 3 contient un éditeur très commode : IDLE que je vous encourage à utiliser. Et deux astuces : attention à l’identation avec Python. Mettez l’extension py pour un script Python classique et pyw pour un script se lançant sans fenêtre. Je le recommande pour ce script.
Si vous souhaitez diffuser votre script Python et qu’il fonctionne sans avoir à installer Python, tournez vous vers py2exe (Utilisateurs avancés : imaginez ce que l’on peut faire en distribuant les calculs via un exe …).
Multithreader PHP grâce à Python
# Limititation : les threads d'utilisent qu'un coeur d'un processeur multicoeur # Ce n'est pas gênant pour l'utilisation escomptée, sachant que la puissance de # calcul n'est pas le facteur limitant, celui-ci étant la latence réseau. # Auteur : Maxime Varinard - Vaisonet - http://www.vaisonet.com # Vous pouvez librement ré-utiliser ce script, mais un petit backlink avec une belle # ancre de votre choix contenant e-commerce serait un beau remerciement ;) import threading, os from tkinter import * th = 0 def lancement(param): global th th = th + 1 # la ligne ci-dessous est à adapter pour lancer les bons programmes/scripts script = '"c:/Program Files/xampp/php/php.exe" c:/Users/Maxime/Desktop/sleep.php ' + param os.system(script) th = th - 1 # On peut lancer manuellement des scripts, hors boucle for (par exemple un script perl) a = threading.Thread(None, lancement, None, ('1',)) b = threading.Thread(None, lancement, None, ('5',)) a.start() b.start() # On lance la boucle des threads # Le tableau li contient les paramètres à passer au script. Il lancera en parallèle les scripts # avec les différents paramètres. li = ['www.siteA.fr', 'www.siteB.fr', 'www.siteC.fr'] for s in li: s = threading.Thread(None, lancement, None, (s,)) s.start() # Le thread qui surveille la fin d'exécution des autres threads # Permet de signaler la fin d'exécution des scripts lancés s'ils n'ont pas de fenêtres def alert(): global th while th > 0: # On ne fait rien continue fen = Tk() fen.title('Outils Vaisonet') tex = Label(fen, text='Les tâches sont terminées !', width=45, height=3) tex.pack() bou = Button(fen, text='Ok', command = fen.destroy) bou.pack() fen.mainloop() print("fini", th) EA = threading.Thread(None, alert, None) EA.start()
Le script est bien commenté, mais voici quelques explications complémentaires pour son intégration avec php. Il faut sortir la boucle foreach de votre script php pour l’intégrer dans le script Python. On appelle ensuite votre script php en ligne de commande. Cela veut donc dire qu’il faut savoir utiliser $argv pour passer le paramètre. Voici un exemple, mon fichier sleep.php de test
echo "toto" . $argv[1]; sleep(30);
Et si vraiment vous voulez tenter de faire du mutlithreading avec php, faites un tour du côté de stream_select.
La solution avec cURL pose parfois des problèmes, mais vous pouvez essayer : Multithreading avec Curl et PHP
Ce n’est pas l’astuce SEO Black Hat de la mort qui tue, mais je suis sûr que vous trouverez des applications qui vous seront utiles ![]()
Bon code.
Commentaires (12)
Catégorie: Scripts PHP
- Ajouter cet article à :
- Del.icio.us -
- Digg
