De nombreux producteurs, consommateurs unique avec python / mod_wsgi
-
19-09-2019 - |
Question
J'ai une application web Pylônes par Apache (mod_wsgi, prefork). En raison d'Apache, il y a plusieurs processus distincts en cours d'exécution mon code d'application en même temps. Certaines des tâches non critiques que l'application ne je veux reporter pour le traitement en arrière-plan pour améliorer les temps de réponse « en direct ». Donc, je pense à la file d'attente de tâches, de nombreux processus Apache en ajoutant des tâches à cette file d'attente, un seul processus Python séparé les traiter un par un et le retrait de la file d'attente.
La file d'attente doit de préférence être persisté sur le disque si la file d'attente des tâches non traitées ne sont pas perdues à cause de panne de courant, redémarrage du serveur, etc. La question est ce serait une façon raisonnable de mettre en œuvre cette file d'attente ?
En ce qui concerne les choses que j'ai essayé: j'ai commencé avec la base de données SQLite simple et seule table pour stocker les éléments de file d'attente. Dans les tests de charge, lorsque le niveau de plus en plus concurrence, j'ai commencé à obtenir des erreurs de base de données « verrouillé », comme prévu. Le correctif de quick'n'dirty était de remplacer SQLite avec MySQL - il gère bien les problèmes de concurrence, mais se sent comme une surpuissance pour la chose simple que je dois faire. DB opérations liées à des files d'attente apparaissent également en bonne place dans mes rapports de profilage.
La solution
Un courtier de messages comme ActiveMQ est une solution idéale ici.
Le pipeline pourrait être la suivante:
- Processus de demande qui est responsable du traitement des requêtes HTTP génère des réponses rapidement et envoie de faible priorité, les tâches lourdes à la file d'attente AMQ.
- Un ou plusieurs autres processus sont abonnés à consommer de la file d'attente AMQ et faire ce qui est destiné à faire avec ces tâches lourdes.
L'exigence de la persistance de la file d'attente est remplie de la boîte depuis ActiveMQ stocke les messages qui ne sont pas encore consommés dans le stockage persistant. En outre, il adapte très bien puisque vous êtes libre de déployer plusieurs applications HTTP, plusieurs applications de consommation et AMQ lui-même sur des machines différentes chacun.
Nous utilisons quelque chose comme ça dans notre projet écrit en Python utilisant STOMP comme protocole de communication sous-jacente .
Autres conseils
Un serveur web (tout serveur web) est multi-producteur, un processus simple consommateur.
Une solution simple est de construire un wsgiref ou le serveur principal de Werkzeug pour gérer vos demandes de back-end.
Depuis ce serveur « back-end » est construit en utilisant la technologie WSGI, il est très, très similaire au serveur Web frontal. Sauf. Il ne produit pas les réponses HTML (JSON est généralement plus simple). En dehors de cela, il est très simple.
Vous concevez les transactions RESTful pour ce backend. Vous utilisez toutes les différentes fonctions WSGI pour l'analyse syntaxique URI, l'autorisation, l'authentification, etc. Vous - en général - ne pas besoin de gestion de session, car les serveurs RESTful ne proposent généralement pas des séances.
Si vous entrez dans de graves problèmes d'évolutivité, vous Enroulez votre serveur principal dans lighttpd ou un autre moteur Web pour créer un back-end multi-thread.