سؤال

أنا أقوم بتشغيل تطبيق django. كان تحت Apache + mod_python من قبل، وكان كل شيء على ما يرام. تحولت إلى lighttpd + fastcgi. الآن أحصل عشوائيا على الاستثناء التالي (لا المكان ولا الوقت الذي يبدو فيه أن يبدو أنه يمكن التنبؤ به). نظرا لأنها عشوائية، فسيظهر إلا بعد التبديل إلى Fastcgi، أفترض أنه له علاقة ببعض الإعدادات.

العثور على عدد قليل من النتائج عند جرف، ولكن يبدو أنهم يرتبطون بوضع MaxRequests = 1. ومع ذلك، يمكنني استخدام الافتراضي، وهو 0.

أي أفكار من أين تبحث عنه؟

ملاحظة. أنا أستخدم postgresql. قد تكون مرتبطة بذلك أيضا، نظرا لأن الاستثناء يظهر عند إجراء استعلام قاعدة البيانات.

 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.
هل كانت مفيدة؟

المحلول 5

في النهاية، قمت بتبديل مرة أخرى إلى Apache + mod_python (كنت أخطاء عشوائية أخرى مع FCGI، بالإضافة إلى هذا واحد) وكل شيء جيد ومستقر الآن.

لا يزال السؤال مفتوحا. في حالة وجود أي شخص لديه هذه المشكلة في المستقبل وحلها يمكنها تسجيل الحل هنا للإشارة المستقبلية. :)

نصائح أخرى

حل ممكن: http://groups.google.com/group/django-users/browse_thread/thread/2C7421CDB9B9948.

حتى وقت قريب كنت فضولي لاختبار هذا على django 1.1.1. هل سيتم إلقاء هذا الاستثناء مرة أخرى ... مفاجأة، كان هناك مرة أخرى. استغرق الأمر مني بعض الوقت لتصحيح هذا، وكان تلميح مفيد هو أنه يظهر فقط عندما يكون (قبل). لذلك بالنسبة لأولئك الذين يحصلون بشكل عشوائي على هذه الاستثناءات، أستطيع أن أقول ... إصلاح الكود الخاص بك :) حسنا .. على محمل الجد، هناك دائما طرق قليلة للقيام بذلك، لذلك اسمحوا لي أن تطبح أين مشكلة أولا. إذا قمت بالوصول إلى قاعدة البيانات عند استيراد أي من وحداتك، مثل تكوين القراءة من قاعدة البيانات، فستحصل على هذا الخطأ. عند بدء تشغيل تطبيق Fastcgi-Prefork الخاص بك، تقوم أولا باستيراد جميع الوحدات النمطية، وفقط بعد هذا الأطفال. إذا كنت قد أنشأت اتصال DB أثناء استيراد جميع عمليات الأطفال سيكون لها نسخة دقيقة من هذا الكائن. يتم إغلاق هذا الصدد في نهاية مرحلة الطلب (إشارة طلب_fined). لذا فإن الطفل الأول الذي سيتم استدعاؤه لمعالجة طلبك، سيغلق هذا الاتصال. ولكن ماذا سيحدث لبقية العمليات الطفل؟ سوف يعتقدون أن لديهم اتصال مفتوح ويفترض أنه يعمل مع DB، لذلك سيؤدي أي عملية DB استثناء. لماذا هذا لا يظهر في نموذج التنفيذ الخيوط؟ أفترض لأن الخيوط تستخدم نفس الكائن ومعرفة متى يتم إغلاق أي مؤشر ترابط آخر. كيف يمكن اصلاح هذا؟ أفضل طريقة هي إصلاح التعليمات البرمجية الخاصة بك ... ولكن هذا يمكن أن يكون صعبا في بعض الأحيان. خيار آخر، في رأيي نظيفا تماما، هو أن أكتب في مكان ما في تطبيقك قطعة صغيرة من التعليمات البرمجية:

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

ليست الفكر المثالي، والتواصل مرتين إلى DB هو الحل البديل في أحسن الأحوال.


الحل الممكن: استخدام تجمع الاتصال (PGPool، PGBouncer)، لذلك لديك اتصالات DB مجمعة ومستقرة، وسلم بسرعة إلى شهواني FCGI.

المشكلة هي أن هذا يؤدي إلى علة أخرى، psycopg2 رفع InterfaceError. لأنه يحاول قطع الاتصال مرتين (PGBouncer بالفعل التعامل مع هذا).

الآن الجاني هو إشارة django طلب_finished. تسليم اتصال.كلوس (), ، وفشل بصوت عال حتى لو تم قطع اتصالها بالفعل. لا أعتقد أن هذا السلوك مطلوب، كما لو كان الطلب قد انتهى بالفعل، ولا نهتم باتصال DB بعد الآن. تصحيح لتصحيح هذا يجب أن يكون بسيطا.

Traceback ذات الصلة:

 /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>

تعامل الاستثناء هنا يمكن أن تضيف المزيد من التساهل:

/usr/local/lib/pothon2.6/dist-packages/django-1.1.1-pain2.6.egg/django/db/__init__.py

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

أو يمكن التعامل معها بشكل أفضل على psycopg2، لذلك عدم رمي أخطاء قاتلة إذا كان كل ما نحاول القيام به هو قطع الاتصال وهو بالفعل هو:

/usr/local/lib/lib/python2.6/dist-packages/django-1.1.1-pain2.6.egg/django/db/__init__.py

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

بخلاف ذلك، أنا قصيرة على الأفكار.

في التبديل، هل قمت بتغيير إصدارات عميل / خادم postgresql؟

لقد رأيت مشاكل مماثلة مع PHP + MySQL، وكان الجاني غير متوافق بين إصدارات العميل / الخادم (على الرغم من أن لديهم نفس النسخة الرئيسية!)

تنبعث منه رائحة مثل مشكلة الخيوط المحتملة. django هو ليس آمنة مضمونة للخيط على الرغم من أن المستندات الموجودة في الملفات تبدو تشير إلى أنه يمكن تشغيل Django / FCGI بهذه الطريقة. حاول تشغيل مع الجبالاد ثم تغلب على حماقة من الخادم. إذا ذهول المشكلة بعيدا ...

ربما يختلف متغير بيئة PythonPrath و Path عن كلا الإعدادتين (Apache + Mod_Python و Lighttpd + Fastcgi).

لقد قمت بإصلاح مشكلة مماثلة عند استخدام نموذج Geodjango لم يكن استخدام Orm الافتراضي لأحد وظائفه. عندما أضفت خطا لإغلاق الاتصال يدويا الخطأ ذهب بعيدا.

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

ما زلت أرى الخطأ عشوائيا (~ 50٪ من الطلبات) عند القيام بالأشياء مع تسجيل دخول المستخدم / جلسات المستخدم.

ذهبت من خلال نفس المشكلة مؤخرا (lighttpd، fastcgi & postgre). بحثت عن حل للأيام دون نجاح، وكما مولعة أخيرة تحولت إلى MySQL. ذهب المشكلة.

لماذا لا تخزين جلسة في ذاكرة التخزين المؤقت؟ تعيين

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

أيضا يمكنك محاولة استخدام postgres مع PGBouncer. (Postgres - خادم Preforce ولا يعجبك العديد من الاتصالات / قطع الاتصال في الوقت)، ولكن أولا تحقق من postgresql.log.

نسخة أخرى - لديك العديد من السجلات في جداول الجلسة و django-admin.py تنظيف استطيع المساعدة.

يمكن أن تكون المشكلة أساسا مع الواردات. أتلست هذا ما حدث لي. كتبت الحل الخاص بي بعد العثور على شيء من الويب. يرجى التحقق من بلدي blogpost هنا: فائدة بيثون بسيطة للتحقق من جميع الواردات في مشروعك

فكورسي هذا لن يساعدك إلا على الوصول إلى حل المشكلة الأصلية بسرعة كبيرة وليس الحل الفعلي لمشكلتك بنفسه.

تغيير من الطريقة = الجمعية إلى الطريقة = حل الخيوط المشكلة بالنسبة لي.

أحاول أن أعطي إجابة لهذا حتى لو كنت لا تستخدم Django ولكن الهرم كإطار. كنت أركض في هذه المشكلة منذ فترة طويلة. كانت المشكلة، أنه من الصعب حقا إنتاج هذا الخطأ للاختبارات ... على أي حال. أخيرا، حلها عن طريق الحفر من خلال الاشياء بأكملها من الجلسات والدورات النحافة والحالات من الجلسات والمحركات والاتصالات وما إلى ذلك وجدت هذا:

http://docs.sqlalchemy.org/en/rel_0_7/core/pooling.html#disconnect-handling-pessimess.

هذا النهج يضيف ببساطة مستمعا إلى تجمع الاتصال للمحرك. في المستمع محددة ثابتة يتم الاستعلام عن قاعدة البيانات. إذا فشلت في محاولة إنشاء اتصال جديد لقاعدة البيانات قبل فشلها على الإطلاق. هام: يحدث هذا قبل إلقاء أي أشياء أخرى إلى قاعدة البيانات. لذلك من الممكن التحقق المسبق التحقق مما يمنع بقية التعليمات البرمجية الخاصة بك من الفشل.

هذا ليس حلا نظيفا لأنه لا يحل الخطأ نفسه لكنه يعمل مثل سحر. أمل أن هذا يساعد شخصاما.

اقتباس قابل للتطبيق:

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

إذا كان أي شخص ما زال يتعامل مع هذا، فتأكد من أن تطبيقك "يفرز بفارغ الصبر" بحيث سائق Python DB الخاص بك (psycopg2 بالنسبة لي) لا تقاسم الموارد بين العمليات.

حل هذه المشكلة على uwsgi عن طريق إضافة lazy-apps = true الخيار، الأمر الذي يسبب عمليات شوكة التطبيقات مباشرة من البوابة، بدلا من انتظار الكتابة عند الكتابة. أتصور مضيفات WSGI / FastCGI الأخرى لديها خيارات مماثلة.

هل فكرت في التخفيض إلى Python 2.5.x (2.5.4 على وجه التحديد)؟ لا أعتقد أن Django سيعتبر ناضجا على Python 2.6 لأن هناك بعض التغييرات غير المتوافقة مع غير متوافق. ومع ذلك، أشك في أن هذا سيحدد مشكلتك.

أيضا، Django 1.0.2 إصلاح بعض الأخطاء الصغيرة الشائنة لذلك تأكد من أنك تعمل. هذا جيد جدا يمكن إصلاح مشكلتك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top