Y at-il une meilleure façon de servir les résultats d'un processus python coûteux, le blocage sur HTTP?

StackOverflow https://stackoverflow.com/questions/1929681

  •  20-09-2019
  •  | 
  •  

Question

Nous avons un service Web qui sert de petits segments arbitraires d'un inventaire fixe des fichiers MP3 plus importants. Les fichiers MP3 sont générés à la volée par une application python. Le modèle est, faire une requête GET à une URL spécifiant les segments que vous souhaitez, obtenir un flux de audio/mpeg en réponse. Ceci est un processus coûteux.

Nous utilisons Nginx comme gestionnaire de requêtes frontal. Nginx prend soin des réponses de mise en cache pour les demandes courantes.

Nous avons d'abord essayé d'utiliser Tornado sur le back-end pour traiter les demandes de Nginx. Comme on peut s'y attendre, l'opération de blocage MP3 Tornado gardé de faire sa chose (E / S asynchrone). Donc, nous avons multithread, ce qui a résolu le problème de blocage, et très bien réalisé. Cependant, il a introduit une condition de course subtile (en charge réelle du monde) que nous n'avons pas été en mesure de diagnostiquer ou reproduire encore. La condition de course corrompt notre sortie MP3.

Nous avons donc décidé de mettre notre application comme simple gestionnaire WSGI derrière Apache / mod_wsgi (encore w / Nginx à l'avant). Cela élimine le problème de blocage et la condition de la course, mais crée une charge en cascade (par exemple Apache crée trop de processses) sur le serveur dans des conditions réelles. Nous travaillons à droite tuning Apache / mod_wsgi maintenant, mais encore à une phase d'essais et d'erreurs. (Mise à jour:.. Nous avons rétablissait Tornado Voir ci-dessous)

Enfin, la question suivante: sommes-nous manque quelque chose? Y at-il une meilleure façon de servir les ressources CPU coûteux sur HTTP?

Mise à jour: Merci à l'article informé de Graham, je suis assez sûr que ce soit un problème de réglage Apache. Dans le temps moyen, nous sommes revenus à l'aide de Tornado et tentent de résoudre le problème la corruption de données.

Pour ceux qui étaient si prompts à jeter plus de fer au problème, Tornado et un peu de multi-threading (malgré le problème de l'intégrité des données introduites par le filetage) gère la charge acceptablement sur un petit (single core) instance Amazon EC2.

Était-ce utile?

La solution

Vous faites l'erreur d'utiliser le mode intégré d'Apache / mod_wsgi? Lire:

http: // Blog .dscpl.com.au / 2009/03 / charge-pointes-et-excessive mémoire usage.html

Assurez-vous d'utiliser le mode démon si vous utilisez Apache / mod_wsgi.

Autres conseils

Avez-vous essayé Frai? Il est un serveur WSGI avec un assortiment flexible de modes de filetage.

Vous pourriez envisager un système de mise en attente avec des méthodes de notification AJAX.

Chaque fois qu'il ya une demande pour votre ressource coûteuse, et cette ressource doit être généré, ajoutez cette demande à la file d'attente (si elle est pas déjà). Cette opération de mise en attente doit renvoyer un ID d'un objet que vous pouvez interroger pour obtenir son statut.

Ensuite, vous devez écrire un service d'arrière-plan qui tourne en threads de travail. Ces travailleurs DEQUEUE simplement la demande, générer les données, puis enregistre l'emplacement des données dans l'objet de la demande.

La page Web peut faire appels AJAX à votre serveur pour connaître les progrès de la génération et de donner un lien vers le fichier une fois qu'il est disponible.

Voici comment les grands sites de médias travaillent - ceux qui doivent faire face à la vidéo en particulier. Il pourrait être surpuissant pour votre travail MP3 cependant.

Vous pouvez également , regardez dans la gestion d'une machine de couple pour répartir la charge. Vos discussions sur Apache va bloquer encore, mais au moins vous ne serez pas consommer des ressources sur le serveur Web.

S'il vous plaît définir « en cascade charge », car il n'a pas de sens commun.

Votre problème le plus probable va être si vous utilisez trop de processus Apache.

Pour une charge comme cela, assurez-vous que vous utilisez le mpm prefork, et assurez-vous vous limiter à un nombre approprié de processus (pas moins d'un par processeur, pas plus de deux).

On dirait que vous faites les bonnes choses - manque juste la puissance du processeur: pouvez-vous déterminer quelle est la charge du processeur dans le processus de génération de ces MP3

Je pense que la prochaine chose que vous avez à faire, il est d'ajouter plus de matériel pour rendre les années MP3 sur d'autres machines. Ou que ou trouver un moyen de fournir des MP3 pré-rendu (vous pouvez peut-être cahce certains de vos médias?)

BTW, mise à l'échelle pour le web a été le thème d'une conférence Keynote de Jacob Kaplan-Moss sur PyCon Brasil cette année, et il est loin d'être un problème fermé. La pile de technologies dont on a besoin pour traiter est tout à fait impressionnable - (je ne pouvais pas trouver une copie en ligne o f la présentation, bien - -Désolé pour cela)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top