Quelque chose que je viens de penser à: p>
Dites que j'écris le code de vue pour mon site Django, et je fais une erreur et crée une boucle infinie. P>
Chaque fois que quelqu'un essaierait d'accéder à la vue, le travailleur affecté à la demande (que ce soit un travailleur gevent ou un fil python) resterait dans une boucle indéfiniment. P>
Si je comprends correctement, le serveur enverrait une erreur de délai d'attente au client après 30 secondes. Mais que se passera-t-il avec le travailleur python? Continuera-t-il de fonctionner indéfiniment? Cela semble dangereux! P>
Imagine J'ai un serveur dans lequel j'ai alloué 10 travailleurs. Je le laisse courir et à un moment donné, un client essaie d'accéder à la vue avec la boucle infinie. Un travailleur y sera assigné et sera effectivement mort jusqu'au redémarrage du serveur suivant. La chose dangereuse est qu'au début, je ne le remarquerais pas, car le site serait tout simplement plus lent, ayant 9 travailleurs au lieu de 10. Mais cela pourrait se reproduire encore et encore pendant une longue période de temps, peut-être des mois. Le site deviendrait progressivement plus lent, jusqu'à ce qu'il soit vraiment lent avec un seul travailleur. P>
Un redémarrage du serveur résoudrait le problème, mais je détesterais que la fonctionnalité de mon site dépendra des redémarrages du serveur. P>
Est-ce un vrai problème qui se passe?
3 Réponses :
Oui, votre analyse est correcte. Le fil de travail / le processus continuera à courir. De plus, s'il n'y a pas d'attente / sommeil dans la boucle, il aura porté la CPU. D'autres threads / processus obtiendront très peu de processeur, ce qui entraînera votre site complet sur la réponse lente. P>
En outre, je ne pense pas que le serveur n'enverra aucune erreur de délai d'attente au client explicitement. Si le délai d'attente TCP est défini, la connexion TCP sera fermée. P>
Le client peut également avoir un délai d'attente pour obtenir une réponse, qui peut entrer en image. P>
Éviter ce code est le meilleur moyen d'éviter ce code. Vous pouvez également avoir un outil de surveillance sur le serveur pour rechercher une utilisation de la CPU / Memory et de notifier à une activité anormale afin que vous puissiez agir. P>
Je viens de tester cela sur le serveur de développement de Django.
Je suppose une façon de l'éviter, sans simplement éviter un code comme celui-ci, serait d'utiliser le threading pour avoir le contrôle des délais d'attente et d'arrêter le fil. P> peut-être peut-être quelque chose comme: p>
En fait, maintenant que je pense, vous pouvez appeler le thread = myTythread () dans une autre fonction afin que vous puissiez y accéder et l'arrêter plus tard. Mais toujours une solution possible?
Je ne comprends vraiment pas comment votre réponse résout quoi que ce soit. Pour une chose, le code doit finir avant i> la réponse est renvoyée. Deuxièmement, vous n'avez même pas montré comment le fil que vous avez créé sera automatiquement arrêté.
Oh, tu as raison, je suppose que je ne pensais pas ça autant. Je suis désolé.
C'est un vrai problème. En cas de gevent, en raison de la commutation de contexte, il peut même arrêter immédiatement votre site Web de répondre. P>
Tout dépend de votre environnement. Par exemple, lors de l'exécution de Django en production via UWSGI, vous pouvez définir Sinon, en raison de l'architecture de réseau, la déconnexion du client n'arrête pas la boucle infinie et, par défaut, il n'y aura aucune réponse du tout - juste un chargement infini. Différentes options de délai d'attente (l'une des quelles Si vous n'utilisez pas GEVENT (ou d'autres threads verts), une boucle infinie aura tendance à prendre 100% de la puissance CPU disponible (limitée à un noyau), éventuellement manger de plus en plus de mémoire, votre site Web fonctionnera donc assez lentement. et / ou timeout vraiment rapide. Django elle-même n'est pas au courant de la demande, de sorte que, comme mentionné précédemment, votre pile d'environnement de production est le moyen de l'empêcher de se produire. Dans le cas d'UWSGI, http: //uwsgi-docs.readthedocs. org / fr / Dernières options.html # Harakiri-Verbose est la voie à suivre. P>
Harakiri imprime la trace de la pile des processus tués: ( https : //uwsgidiocs.readthedocs.org/fr/latest/traceBacker.html? Highlight = Harakiri ) directement au journal UWSGI, et en raison du système d'alarme, vous pouvez être notifié via e-mail ( http://uwsgi-docs.readthedocs.org/en/latest/alarmsubsystem.html ) p> harakiri code> - c'est l'heure en secondes, après quoi la manipulation du fil de la demande sera tuée si elle n'a pas fini de manipuler la réponse. Il est fortement recommandé de définir une telle valeur afin de traiter certaines demandes défectueuses ou un mauvais code. Cet événement est signalé dans le journal UWSGI. Je crois que d'autres solutions pour la gestion de Django dans la production ont des options similaires. P>
harakiri code> est) peut finir par montrer le délai de connexion - par exemple, PHP a (autant que je me souvienne) du délai d'attente par défaut de 30 secondes et il renvoie 504 timets de passerelle. Délai de déconnexion de socket dépend des paramètres de serveur HTTP et n'arrêtera pas le thread d'applications, il ne fermera que la prise du client. P>
L'option Harakiri est une étape dans la bonne direction, car elle empêche le serveur d'être bloqué, mais cela ne vous aide pas à trouver la racine du problème et à le réparer. Ce que je voudrais, c'est d'avoir une stacktrace du travailleur offensant envoyé par courrier électronique afin que je puisse inspecter et résoudre le problème dans le code.
Harakiri imprime des informations sur la trace de la pile et les demandes de la pile, et Nginx Alarm System permet la notification par courrier électronique. Réponse mise à jour avec des liens.
lire intéressant: Stackoverflow.com/Questtions/8685695/...
J'ai mis à jour ma réponse, j'espère que ça répond à votre question maintenant :)