Question

Je suis en cours d'exécution d'une application Django. Si elle avait sous Apache + mod_python avant, et il était OK. Switched Lighttpd + FastCGI. Maintenant, je reçois au hasard l'exception suivante (ni le lieu ni le moment où il semble semble être prévisible). Comme il est aléatoire, et il semble qu'après le passage à FastCGI, je suppose qu'il a quelque chose à voir avec certains paramètres.

trouvé quelques résultats quand googleing, mais ils semblent être liés à la mise en maxrequests = 1. Cependant, j'utilise la valeur par défaut, qui est 0.

Toutes les idées où chercher?

PS. J'utilise PostgreSQL. Pourrait être liée à cela aussi, puisque l'exception apparaît lors d'une requête de base de données.

 File "/usr/lib/python2.6/site-packages/django/core/handlers/base.py", line 86, in get_response
   response = callback(request, *callback_args, **callback_kwargs)

 File "/usr/lib/python2.6/site-packages/django/contrib/admin/sites.py", line 140, in root
   if not self.has_permission(request):

 File "/usr/lib/python2.6/site-packages/django/contrib/admin/sites.py", line 99, in has_permission
   return request.user.is_authenticated() and request.user.is_staff

 File "/usr/lib/python2.6/site-packages/django/contrib/auth/middleware.py", line 5, in __get__
   request._cached_user = get_user(request)

 File "/usr/lib/python2.6/site-packages/django/contrib/auth/__init__.py", line 83, in get_user
   user_id = request.session[SESSION_KEY]

 File "/usr/lib/python2.6/site-packages/django/contrib/sessions/backends/base.py", line 46, in __getitem__
   return self._session[key]

 File "/usr/lib/python2.6/site-packages/django/contrib/sessions/backends/base.py", line 172, in _get_session
   self._session_cache = self.load()

 File "/usr/lib/python2.6/site-packages/django/contrib/sessions/backends/db.py", line 16, in load
   expire_date__gt=datetime.datetime.now()

 File "/usr/lib/python2.6/site-packages/django/db/models/manager.py", line 93, in get
   return self.get_query_set().get(*args, **kwargs)

 File "/usr/lib/python2.6/site-packages/django/db/models/query.py", line 304, in get
   num = len(clone)

 File "/usr/lib/python2.6/site-packages/django/db/models/query.py", line 160, in __len__
   self._result_cache = list(self.iterator())

 File "/usr/lib/python2.6/site-packages/django/db/models/query.py", line 275, in iterator
   for row in self.query.results_iter():

 File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 206, in results_iter
   for rows in self.execute_sql(MULTI):

 File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1734, in execute_sql
   cursor.execute(sql, params)

OperationalError: server closed the connection unexpectedly
       This probably means the server terminated abnormally
       before or while processing the request.
Était-ce utile?

La solution 5

En fin de compte je suis revenu à Apache + mod_python (j'avais d'autres erreurs aléatoires avec fcgi, en plus de celui-ci) et tout est bon et stable maintenant.

La question reste ouverte. Dans le cas où quelqu'un a ce problème à l'avenir et résout ils peuvent enregistrer ici la solution pour référence future. :)

Autres conseils

Solution possible: http://groups.google.com/ groupe / django-users / browse_thread / fil / 2c7421cdb9b99e48

  

Jusqu'à récemment, je suis curieux de tester   ceci sur Django 1.1.1. Cela va-t-il   exception être jeté à nouveau ... surprise,   là, il était à nouveau. Il m'a fallu un certain   le temps de débugger, conseil utile était   qu'il montre que lorsque (pré) bifurquer.   Donc, pour ceux qui se au hasard   ces exceptions, je peux dire ... corriger   votre code :) Ok .. sérieusement, il   sont toujours quelques façons de le faire, donc   permettez-moi de sapins expliquer où est   Le premier problème. Si vous accédez à la base de données   lorsque l'un de vos modules importera   comme, par exemple lecture de la configuration de   base de données, vous obtiendrez cette erreur.   Lorsque votre application FastCGI-prefork   commence, d'abord, il importe tous les modules,   et seulement après ces enfants fourches.   Si vous avez établi une connexion db   lors de l'importation de tous les processus enfants   aura une copie exacte de cette   objet. Cette connexion est   fermé à la fin de la phase de demande   (Signal de request_finished). Alors d'abord   enfant qui sera appelé à traiter   votre demande, fermera ses portes ce   lien. Mais ce qui arrivera à   le reste des processus enfants? Ils   croira qu'ils ont ouvert et   connexion sans doute au travail   db, de sorte que toute opération db provoquera une   exception. Pourquoi ce ne montre pas dans   modèle d'exécution filetée? Je suppose   parce que les sujets utilisent un même objet   et savoir quand tout autre fil est   fermeture de la connexion. Comment régler ceci?   La meilleure façon est de fixer votre code ... mais   cela peut être parfois difficile.   Une autre option, tout à fait à mon avis   propre, est d'écrire quelque part dans votre   l'application petit morceau de code:

from django.db import connection 
from django.core import signals 
def close_connection(**kwargs): 
    connection.close() 
signals.request_started.connect(close_connection) 

Non pensée idéale, reliant deux fois à la base de données est une solution de contournement au mieux.


Solution possible:. Utilisant la mise en commun connexion (pgpool, de pgbouncer), de sorte que vous avez des connexions DB mis en commun et stable, et remis rapidement à vos daemons FCGI

Le problème est que cela déclenche un autre bug, psycopg2 soulevant un InterfaceError parce qu'il essaie de déconnecter deux fois (pgbouncer déjà traité ce sujet).

Maintenant, le coupable est un signal Django request_finished déclenchement connection.close () , et à défaut fort, même si elle était déjà déconnecté. Je ne pense pas que ce comportement est souhaité, comme si la demande déjà terminée, nous ne nous soucions pas de la connexion DB plus. Un patch pour corriger cela devrait être simple.

Le retraçage pertinent:

 /usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/core/handlers/wsgi.py in __call__(self=<django.core.handlers.wsgi.WSGIHandler object at 0x24fb210>, environ={'AUTH_TYPE': 'Basic', 'DOCUMENT_ROOT': '/storage/test', 'GATEWAY_INTERFACE': 'CGI/1.1', 'HTTPS': 'off', 'HTTP_ACCEPT': 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_AUTHORIZATION': 'Basic dGVzdGU6c3VjZXNzbw==', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_COOKIE': '__utma=175602209.1371964931.1269354495.126938948...none); sessionid=a1990f0d8d32c78a285489586c510e8c', 'HTTP_HOST': 'www.rede-colibri.com', ...}, start_response=<function start_response at 0x24f87d0>)
  246                 response = self.apply_response_fixes(request, response)
  247         finally:
  248             signals.request_finished.send(sender=self.__class__)
  249 
  250         try:
global signals = <module 'django.core.signals' from '/usr/local/l.../Django-1.1.1-py2.6.egg/django/core/signals.pyc'>, signals.request_finished = <django.dispatch.dispatcher.Signal object at 0x1975710>, signals.request_finished.send = <bound method Signal.send of <django.dispatch.dispatcher.Signal object at 0x1975710>>, sender undefined, self = <django.core.handlers.wsgi.WSGIHandler object at 0x24fb210>, self.__class__ = <class 'django.core.handlers.wsgi.WSGIHandler'>
 /usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/dispatch/dispatcher.py in send(self=<django.dispatch.dispatcher.Signal object at 0x1975710>, sender=<class 'django.core.handlers.wsgi.WSGIHandler'>, **named={})
  164 
  165         for receiver in self._live_receivers(_make_id(sender)):
  166             response = receiver(signal=self, sender=sender, **named)
  167             responses.append((receiver, response))
  168         return responses
response undefined, receiver = <function close_connection at 0x197b050>, signal undefined, self = <django.dispatch.dispatcher.Signal object at 0x1975710>, sender = <class 'django.core.handlers.wsgi.WSGIHandler'>, named = {}
 /usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/__init__.py in close_connection(**kwargs={'sender': <class 'django.core.handlers.wsgi.WSGIHandler'>, 'signal': <django.dispatch.dispatcher.Signal object at 0x1975710>})
   63 # when a Django request is finished.
   64 def close_connection(**kwargs):
   65     connection.close()
   66 signals.request_finished.connect(close_connection)
   67 
global connection = <django.db.backends.postgresql_psycopg2.base.DatabaseWrapper object at 0x17b14c8>, connection.close = <bound method DatabaseWrapper.close of <django.d...ycopg2.base.DatabaseWrapper object at 0x17b14c8>>
 /usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/backends/__init__.py in close(self=<django.db.backends.postgresql_psycopg2.base.DatabaseWrapper object at 0x17b14c8>)
   74     def close(self):
   75         if self.connection is not None:
   76             self.connection.close()
   77             self.connection = None
   78 
self = <django.db.backends.postgresql_psycopg2.base.DatabaseWrapper object at 0x17b14c8>, self.connection = <connection object at 0x1f80870; dsn: 'dbname=co...st=127.0.0.1 port=6432 user=postgres', closed: 2>, self.connection.close = <built-in method close of psycopg2._psycopg.connection object at 0x1f80870>

La gestion des exceptions ici pourrait ajouter plus de clémence:

/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db / __ __ initialisation. Py

   63 # when a Django request is finished.
   64 def close_connection(**kwargs):
   65     connection.close()
   66 signals.request_finished.connect(close_connection)

Ou il pourrait être traité mieux sur psycopg2, afin de ne pas jeter des erreurs fatales si tout ce que nous essayons de faire est de déconnecter et il est déjà:

/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/backends / __ __ initialisation. Py

   74     def close(self):
   75         if self.connection is not None:
   76             self.connection.close()
   77             self.connection = None

Autre que cela, je suis à court d'idées.

Dans le commutateur, avez-vous changé PostgreSQL versions client / serveur?

J'ai vu des problèmes similaires avec php + mysql, et le coupable était une incompatibilité entre les versions client / serveur (même si elles ont la même version majeure!)

Smells comme un problème de filetage possible. Django est pas thread-safe garantie bien que les documents en fichier semblent indiquer que Django / FCGI peut fonctionner de cette façon. Essayez d'exécuter avec prefork puis battre la merde hors du serveur. Si le problème disparaît ...

Peut-être la variable PYTHONPATH et environnement PATH est différent pour les deux configurations (Apache + mod_python et lighttpd + FastCGI).

Correction d'un problème similaire lors de l'utilisation d'un modèle de GeoDjango qui n'a pas été en utilisant l'ORM par défaut pour l'une de ses fonctions. Quand j'ai ajouté une ligne pour fermer manuellement la connexion l'erreur a disparu.

http://code.djangoproject.com/ticket/9437

Je vois toujours l'erreur au hasard (~ 50% des demandes) lorsque vous faites des choses avec connexion utilisateur / sessions cependant.

Je suis passé par le même problème récemment (lighttpd, FastCGI et postgre). Recherché une solution pour les jours sans succès, et en dernier recours commuté à MySQL. Le problème a disparu.

Pourquoi ne pas stocker session en cache? Set

SESSION_ENGINE = "django.contrib.sessions.backends.cache"

Vous pouvez également essayer postgres d'utilisation avec pgbouncer . (Postgres - serveur prefork et n'aiment pas beaucoup / déconnexions par Relie temps), mais tout d'abord vérifier votre postgresql.log

Une autre version -. Vous avez plusieurs enregistrements dans les tables de session et nettoyage django-admin.py peut aider

Le problème pourrait être principalement avec les importations. Atleast thats ce qui est arrivé à moi. J'ai écrit ma propre solution après avoir trouvé rien à partir du Web. S'il vous plaît vérifier mon blogpost ici: Utilitaire simple Python pour vérifier toutes les importations en votre projet

Ofcourse cela ne fera que vous aider à arriver à la solution de la question initiale assez rapidement et non la solution réelle pour votre problème en lui-même.

= méthode de changement prefork à la méthode = filetée a résolu le problème pour moi.

J'essaie de donner une réponse à cette même si I'am ne pas utiliser django mais pyramide comme cadre. Je courais dans ce problème depuis longtemps. Le problème était qu'il était vraiment difficile de produire cette erreur pour les tests ... Quoi qu'il en soit. Enfin je l'ai résolu en creusant à travers l'ensemble des choses, séances scope, les instances des sessions, des moteurs et des connexions, etc. Je trouve ceci:

http://docs.sqlalchemy.org/ fr / rel_0_7 / core / pooling.html # déconnexion de manutention-pessimiste

Cette approche ajoute simplement un auditeur à la piscine de connexion du moteur. Dans l'auditeur une sélection statique est la base de données interrogé. Si elle échoue la piscine essayez d'établir une nouvelle connexion à la base de données avant qu'il ne tombe en panne à tout. Important: Cela se produit avant toute autre substance est jeté à la base de données. Il est donc possible d'effectuer une pré connexion à cocher ce qui empêche le reste de votre code de défaut.

Ce n'est pas une solution propre car il ne résout pas l'erreur elle-même, mais cela fonctionne comme un charme. Espérons que cela aide quelqu'un.

Une citation applicable:

"2019 anyone?" - half of YouTube comments, circa 2019

Si quelqu'un est toujours aux prises avec cela, assurez-vous que votre application est « avec impatience bifurquer » de telle sorte que votre pilote DB Python (de psycopg2 pour moi) ne partage des ressources entre les processus.

Je résolu cette question uwsgi en ajoutant l'option lazy-apps = true, ce qui provoque est à fork d'application dès la sortie de la porte, plutôt que d'attendre la copie en écriture. J'imagine que d'autres hôtes WSGI / FastCGI ont des options similaires.

Avez-vous envisagé à Python 2.5.x dévalorisation (2.5.4 spécifiquement)? Je ne pense pas que Django serait considéré comme matures sur Python 2.6 car il y a des changements en arrière incompatibles. Cependant, je doute que cela va résoudre votre problème.

En outre, Django 1.0.2 a corrigé quelques petits bugs infâmes font donc que vous exécutez cela. Ce pourrait très bien résoudre votre problème.

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