Nous avons un service Web qui sert de petits segments arbitraires d'un inventaire fixe de gros fichiers MP3. Les fichiers MP3 sont générés à la volée par une application python. Le modèle est, faire une demande GET à une URL en spécifiant quels segments vous voulez, obtenir un flux audio/mpeg
en réponse. C'est un processus coûteux.Existe-t-il un meilleur moyen de diffuser les résultats d'un processus python bloquant coûteux sur HTTP?
Nous utilisons Nginx comme gestionnaire de requêtes frontal. Nginx prend soin de la mise en cache des réponses pour les demandes courantes.
Nous avons d'abord essayé d'utiliser Tornado sur le back-end pour traiter les demandes de Nginx. Comme vous pouvez vous y attendre, l'opération de blocage du MP3 a empêché Tornado de faire son truc (E/S asynchrones). Donc, nous sommes allés multithread, ce qui a résolu le problème de blocage, et a très bien fonctionné. Cependant, il a introduit une condition de course subtile (sous la charge du monde réel) que nous n'avons pas encore pu diagnostiquer ou reproduire. La condition de course corrompt notre sortie MP3.
Nous avons donc décidé de définir notre application comme un simple gestionnaire WSGI derrière Apache/mod_wsgi (toujours avec Nginx à l'avant). Cela élimine le problème de blocage et la condition de concurrence, mais crée une charge en cascade (c'est-à-dire qu'Apache crée trop de processus) sur le serveur dans des conditions réelles. Nous travaillons actuellement sur le réglage d'Apache/mod_wsgi, mais toujours dans une phase d'essai et d'erreur. (Mise à jour: nous sommes retournés à Tornado, voir ci-dessous.)
Enfin, la question: avons-nous oublié quelque chose? Existe-t-il une meilleure façon de traiter les ressources coûteuses en ressources CPU sur HTTP?
Mise à jour: Merci à l'article informé de Graham, je suis sûr qu'il s'agit d'un problème de réglage Apache. En attendant, nous sommes retournés à Tornado et essayons de résoudre le problème de corruption de données. Pour ceux qui ont été si rapides à jeter plus de fer sur le problème, Tornado et un peu de multi-threading (malgré le problème d'intégrité des données introduit par thread) gère la charge de manière acceptable sur une petite instance Amazon EC2 .
Excellent article. Merci. Cela pourrait finir par faire l'affaire. –
En fait, je vais accepter ce lien comme la meilleure réponse, car le problème semble être un problème de réglage Apache. –