33 votes

Traitement asynchrone ou files de messages en PHP (CakePHP)

Je suis en train de construire un site Web en CakePHP qui traite les fichiers téléchargés via une API XML-RPC et via un frontal Web. Les fichiers doivent être analysés par ClamAV, les vignettes doivent être générées, etc. Autant de tâches gourmandes en ressources qui prennent un certain temps et pour lesquelles l'utilisateur ne devrait pas avoir à attendre. Je m'intéresse donc au traitement asynchrone avec PHP en général et CakePHP en particulier.

Je suis tombé sur le Plugin MultiTask pour CakePHP qui semble prometteur. Je suis également tombé sur diverses implémentations de files d'attente de messages telles que dropr et tige de haricot . Bien sûr, j'aurai également besoin d'une sorte de processus d'arrière-plan, probablement implémenté en utilisant une sorte de Cake Shell. J'ai vu MultiTask utiliser PHP_Fork pour implémenter un démon PHP multithread.

J'ai besoin de conseils sur la manière d'assembler toutes ces pièces de la meilleure façon possible.

  • Est-ce une bonne idée d'avoir un démon de longue durée écrit en PHP ? À quoi dois-je faire attention ?
  • Quels sont les avantages des implémentations externes de files de messages ? Le plugin MultiTask n'utilise pas de file d'attente de messages externe. Il roule le sien en utilisant une table MySQL pour stocker les tâches.
  • Quelle file d'attente de messages dois-je utiliser ? dropr ? beanstalkd ? Quelque chose d'autre ?
  • Comment dois-je implémenter le processeur dorsal ? Est-ce qu'un démon PHP qui bifurque est une bonne idée ou est-ce que je vais avoir des problèmes ?

Mon plan actuel est soit d'utiliser le plugin MultiTask, soit de le modifier pour utiliser beanstald au lieu de sa propre implémentation de table MySQL. Les tâches dans la file d'attente peuvent simplement consister en un nom de tâche et un tableau de paramètres. Le démon PHP surveille les tâches entrantes et les transmet à l'un de ses threads enfants. Celui-ci exécutera simplement la tâche CakePHP avec les paramètres donnés.

Un avis, un conseil, un commentaire, un problème ou une flamme à ce sujet ?

25voto

Alister Bulman Points 12913

J'ai eu d'excellents résultats avec BeanstalkD et un back-end écrit en PHP pour récupérer les travaux et y donner suite. J'ai enveloppé l'exécution de la tâche dans un bash-script pour qu'elle se poursuive même si elle se termine (à moins que je fasse un ' exit(UNIQNUM); ', lorsque le script le vérifie et va effectivement sortir). De cette façon, le script PHP redémarré efface toute la mémoire qui a pu être utilisée, et peut recommencer tous les 25/50/100 travaux qu'il exécute.

Un des avantages de son utilisation est que vous pouvez définir des priorités et des délais dans un travail BeanstalkD - "exécutez ceci avec une priorité inférieure, mais ne démarrez pas avant 10 secondes". J'ai également mis en file d'attente un certain nombre de tâches au même moment (exécuter ceci maintenant, dans 5 secondes et encore après 30 secondes).

Avec la configuration réseau appropriée (et en l'exécutant sur une adresse IP accessible au reste de votre réseau), vous pouvez également exécuter un démon beanstalkd sur un serveur, et le faire interroger par un certain nombre d'autres machines, de sorte que si un grand nombre de tâches sont générées, le travail peut être réparti entre les serveurs. Si un ensemble particulier de tâches doit être exécuté sur une machine particulière, j'ai créé un 'tube' qui est le nom d'hôte de cette machine, qui devrait être unique dans notre cluster, sinon globalement (utile pour les téléchargements de fichiers). J'ai trouvé que cela fonctionnait parfaitement pour le redimensionnement des images, renvoyant souvent les images finies plus petites vers le système de fichiers avant que la page web elle-même qui y ferait référence ne renvoie à l'URL à laquelle elle arriverait.

En fait, je suis sur le point de commencer à écrire une série d'articles sur ce sujet précis pour mon blog (y compris certaines techniques pour le code que j'ai déjà fait passer par plusieurs millions de demandes en direct) - Mon URL est liée à mon profil de l'utilisateur ici, sur Stackoverflow.

(J'ai écrit un série d'articles sur le sujet de Beanstalkd et de la mise en file d'attente des travaux)

4voto

Peter Stuifzand Points 3160

Si vous utilisez une file d'attente de messages comme beanstalkd, vous pouvez lancer autant de processus que vous le souhaitez (même sur le même serveur). Chaque processus ouvrier prendra un travail dans la file d'attente et le traitera. Vous pouvez ajouter plus de travailleurs et plus de serveurs si vous avez besoin de plus de capacité.

L'avantage d'utiliser un travailleur à un seul fil est que vous n'avez pas à gérer la synchronisation à l'intérieur d'un processus. La file d'attente des tâches permet de s'assurer qu'aucune tâche ne sera traitée deux fois.

0voto

neilcrookes Points 3470

Cela pourrait également valoir la peine de vérifier Amazon SQS à utiliser en conjonction avec EC2 ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X