Ich führe eine Django-Anwendung aus. Hatte es unter Apache + mod_python schon, und es war alles in Ordnung. Auf Lighttpd + FastCGI umgeschaltet. Jetzt bekomme ich zufällig die folgende Ausnahme (weder der Ort noch die Zeit, wo es erscheint, scheinen vorhersehbar zu sein). Da es zufällig ist und erst nach dem Wechsel zu FastCGI erscheint, nehme ich an, dass es etwas mit einigen Einstellungen zu tun hat.
Einige Ergebnisse beim googlen gefunden, aber sie scheinen mit der Einstellung von maxrequests = 1 in Zusammenhang zu stehen. Ich verwende jedoch den Standardwert 0.
Irgendwelche Ideen, wo man suchen sollte?
PS. Ich benutze PostgreSQL. Könnte auch damit verwandt sein, da die Ausnahme beim Erstellen einer Datenbankabfrage erscheint.
%Vor%Am Ende habe ich wieder zu Apache + mod_python gewechselt (ich hatte andere zufällige Fehler mit fcgi, außer diesem) und alles ist jetzt gut und stabil.
Die Frage bleibt offen. Falls jemand dieses Problem in der Zukunft hat und es löst, kann es die Lösung hier für zukünftige Referenz aufzeichnen. :)
Mögliche Lösung: Ссылка
%Vor%Bis vor kurzem war ich neugierig zu testen dies auf Django 1.1.1. Wird das Ausnahme wird wieder geworfen ... Überraschung, Da war es wieder. Es hat mich etwas gekostet Zeit, um dies zu debuggen, war hilfreicher Hinweis dass es nur beim (Vor) Gabeln zeigt. Also für diejenigen, die zufällig kommen Diese Ausnahmen kann ich sagen ... reparieren Dein Code :) Ok .. ernsthaft, da Es gibt immer wenige Möglichkeiten, dies zu tun lassen Sie mich erklären, wo ist ein Problem zuerst. Wenn Sie auf die Datenbank zugreifen wenn eines Ihrer Module importiert wird als z.B. Konfiguration lesen von Datenbank dann erhalten Sie diesen Fehler. Wenn Ihre Fastcgi-Prefork-Anwendung startet, zuerst importiert es alle Module, und erst danach gibt es Kinder. Wenn Sie eine db-Verbindung hergestellt haben Beim Import werden alle Kinderprozesse ausgeführt wird eine genaue Kopie davon haben Objekt. Diese Verbindung wird hergestellt geschlossen am Ende der Anfragephase (request_finished Signal). So zuerst Kind, das zur Bearbeitung angerufen wird Ihre Anfrage, wird dies schließen Verbindung. Aber was wird passieren der Rest der Kindprozesse? Sie Ich glaube, dass sie offen und offen sind vermutlich funktionierende Verbindung zum db, also wird jede db-Operation eine verursachen Ausnahme. Warum das nicht angezeigt wird Gewinde-Ausführungsmodell? Ich nehme an weil Threads dasselbe Objekt verwenden und wissen, wenn ein anderer Thread ist schließende Verbindung. Wie behebe ich das? Der beste Weg ist, Ihren Code zu reparieren ... aber Das kann manchmal schwierig sein. Andere Option, meiner Meinung nach ziemlich sauber, ist irgendwo in deinem schreiben Anwendung kleines Stück Code:
Nicht ideal, wenn Sie zweimal mit der DB verbinden, ist das ein Workaround.
Mögliche Lösung: Verbindungspooling (pgpool, pgbouncer) verwenden, so dass Sie DB-Verbindungen gesammelt und stabil haben und schnell an Ihre FCGI-Daemons übergeben werden.
Das Problem ist, dass dies einen anderen Fehler auslöst, psycopg2, der einen InterfaceError auslöst, weil er versucht, die Verbindung zweimal zu trennen (pgbouncer hat das bereits erledigt).
Nun ist der Schuldige Django-Signal request_finished , das connection.close () triggert, und es schlägt laut, selbst wenn es bereits getrennt war. Ich glaube nicht, dass dieses Verhalten erwünscht ist, als ob die Anfrage bereits beendet wäre, uns ist die DB-Verbindung nicht mehr wichtig. Ein Patch zur Korrektur sollte einfach sein.
Die relevante Rückverfolgung:
%Vor%Ausnahmebehandlung könnte hier mehr Nachsicht bringen:
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/__init__py
%Vor%Oder es könnte besser auf psycopg2 gehandhabt werden, also keine fatalen Fehler zu werfen, wenn alles, was wir zu tun versuchen, ist trennen und es ist bereits:
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/backends/__init__py
%Vor%Abgesehen davon, habe ich Ideen.
Riecht wie ein mögliches Threading-Problem. Django ist nicht garantiert threadsicher, obwohl die in der Datei enthaltenen Dokumente darauf hindeuten, dass Django / FCGI auf diese Weise ausgeführt werden kann. Versuchen Sie, mit Prefork zu laufen und dann den Mist aus dem Server zu schlagen. Wenn das Problem verschwindet ...
Ich habe ein ähnliches Problem behoben, wenn ich ein Geodjangomodell verwende, das nicht das Standard-ORM für eine seiner Funktionen verwendet. Als ich eine Leitung hinzufügte, um die Verbindung manuell zu schließen, ging der Fehler weg.
Ich sehe den Fehler immer noch zufällig (~ 50% der Anfragen), wenn ich Sachen mit Benutzeranmeldungen / Sitzungen mache.
Warum nicht Sitzung im Cache speichern? Stellen Sie
ein %Vor%Sie können auch Postgres mit pgbouncer verwenden (postgres - prefork server und mögen nicht viele connections / disconnects pro Zeit), aber überprüfen Sie zuerst Ihre postgresql.log.
Eine andere Version - Sie haben viele Datensätze in Sitzungstabellen und django-admin.py cleanup kann Ihnen helfen.
Das Problem könnte hauptsächlich bei Importen liegen. Zumindest ist das mit mir passiert. Ich habe meine eigene Lösung geschrieben, nachdem ich nichts aus dem Internet gefunden habe. Bitte überprüfe meinen Blogpost hier: Simple Python Utility, um alle Importe in deinem Projekt zu überprüfen
Natürlich hilft Ihnen das nur, die Lösung des ursprünglichen Problems schnell zu finden und nicht die eigentliche Lösung für Ihr Problem.
Von Methode = prefork zu method = threaded hat das Problem für mich gelöst.
Ich versuche, eine Antwort darauf zu geben, auch wenn ich nicht Django, sondern Pyramide als Rahmen benutze. Ich bin seit langem auf dieses Problem gestoßen. Problem war, dass es wirklich schwierig war, diesen Fehler für Tests zu erzeugen ... Jedenfalls. Schließlich habe ich es gelöst, indem ich mich durch das ganze Zeug von Sessions, Scoped Sessions, Instanzen von Sessions, Engines und Connections etc. gekümmert habe. Ich habe folgendes gefunden:
Dieser Ansatz fügt dem Verbindungspool der Engine einfach einen Listener hinzu. Im Listener wird eine statische Auswahl an die Datenbank abgefragt. Wenn der Pool fehlschlägt, versuchen Sie, eine neue Verbindung zur Datenbank herzustellen, bevor überhaupt ein Fehler auftritt. Wichtig: Dies geschieht, bevor irgendwelche anderen Sachen in die Datenbank geworfen werden. So ist es möglich, die Verbindung vorab zu überprüfen, was verhindert, dass der Rest Ihres Codes fehlschlägt.
Dies ist keine saubere Lösung, da es nicht den Fehler selbst löst, aber es funktioniert wie ein Zauber. Hoffe, das hilft jemandem.
Haben Sie erwogen, auf Python 2.5.x herunterzuspielen (speziell 2.5.4)? Ich denke nicht, dass Django auf Python 2.6 als ausgereift gelten würde, da es einige rückwärtskompatible Änderungen gibt. Ich bezweifle jedoch, dass dies Ihr Problem beheben wird.
Außerdem hat Django 1.0.2 einige schändliche kleine Bugs behoben, also stelle sicher, dass du das ausführst. Das könnte Ihr Problem beheben.