ibz*_*ibz 8 python django fastcgi lighttpd exception
我正在运行Django应用程序.以前在Apache + mod_python下,它一切都好.切换到Lighttpd + FastCGI.现在我随机获得以下异常(地点和出现的时间似乎都不可预测).由于它是随机的,并且只在切换到FastCGI之后出现,我认为它与某些设置有关.
谷歌时发现了一些结果,但它们似乎与设置maxrequests = 1有关.但是,我使用默认值,即0.
任何想法在哪里寻找?
PS.我正在使用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.
Run Code Online (Sandbox Code Playgroud)
可能的解决方案:http : //groups.google.com/group/django-users/browse_thread/thread/2c7421cdb9b99e48
直到最近我才想在 Django 1.1.1 上测试这个。会不会再次抛出这个异常......惊喜,它又出现了。我花了一些时间来调试这个,有用的提示是它只在(预)分叉时显示。因此,对于那些随机获得这些异常的人,我可以说...修复您的代码 :) 好吧...说真的,这样做的方法总是很少,所以让我先解释一下哪里出了问题。如果您在任何模块导入时访问数据库,例如从数据库读取配置,那么您将收到此错误。当您的 fastcgi-prefork 应用程序启动时,它首先会导入所有模块,并且只有在此之后才会对子项进行分叉。如果您在导入期间建立了 db 连接,则所有子进程都将拥有该对象的精确副本。此连接在请求阶段结束时关闭(request_finished 信号)。因此,将被调用来处理您的请求的第一个孩子将关闭此连接。但是其余的子进程会发生什么?他们会相信他们已经打开并且大概可以工作到数据库的连接,因此任何数据库操作都会导致异常。为什么这没有显示在线程执行模型中?我想是因为线程使用相同的对象并且知道任何其他线程何时关闭连接。如何解决这个问题?最好的方法是修复您的代码……但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:因此,将被调用来处理您的请求的第一个孩子将关闭此连接。但是其余的子进程会发生什么?他们会相信他们已经打开并且大概可以工作到数据库的连接,因此任何数据库操作都会导致异常。为什么这没有显示在线程执行模型中?我想是因为线程使用相同的对象并且知道任何其他线程何时关闭连接。如何解决这个问题?最好的方法是修复您的代码……但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:因此,将被调用来处理您的请求的第一个孩子将关闭此连接。但是其余的子进程会发生什么?他们会相信他们已经打开并且大概可以工作到数据库的连接,因此任何数据库操作都会导致异常。为什么这没有显示在线程执行模型中?我想是因为线程使用相同的对象并且知道任何其他线程何时关闭连接。如何解决这个问题?最好的方法是修复您的代码……但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:但是其余的子进程会发生什么?他们会相信他们已经打开并且大概可以工作到数据库的连接,因此任何数据库操作都会导致异常。为什么这没有显示在线程执行模型中?我想是因为线程使用相同的对象并且知道任何其他线程何时关闭连接。如何解决这个问题?最好的方法是修复您的代码……但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:但是其余的子进程会发生什么?他们会相信他们已经打开并且大概可以工作到数据库的连接,因此任何数据库操作都会导致异常。为什么这没有显示在线程执行模型中?我想是因为线程使用相同的对象并且知道任何其他线程何时关闭连接。如何解决这个问题?最好的方法是修复您的代码……但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:但这有时可能很困难。其他选项,在我看来很干净,是在你的应用程序的某个地方写一小段代码:
from django.db import connection
from django.core import signals
def close_connection(**kwargs):
connection.close()
signals.request_started.connect(close_connection)
Run Code Online (Sandbox Code Playgroud)
不是理想的想法,连接两次到数据库充其量是一种解决方法。
可能的解决方案:使用连接池(pgpool、pgbouncer),这样你就有了池化和稳定的数据库连接,并快速传递给你的 FCGI 守护进程。
问题是这会触发另一个错误, psycopg2 引发InterfaceError因为它试图断开两次连接(pgbouncer 已经处理了这个)。
现在罪魁祸首是 Django 信号request_finished触发了connection.close(),即使它已经断开连接也会大声失败。我不认为这种行为是可取的,就好像请求已经完成一样,我们不再关心数据库连接。用于纠正此问题的补丁应该很简单。
相关回溯:
/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>
Run Code Online (Sandbox Code Playgroud)
这里的异常处理可以增加更多的宽大处理:
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.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)
Run Code Online (Sandbox Code Playgroud)
或者它可以在 psycopg2 上更好地处理,所以如果我们试图做的只是断开连接并且它已经是:
/usr/local/lib/python2.6/dist-packages/Django-1.1.1-py2.6.egg/django/db/backends/__init__.py
74 def close(self):
75 if self.connection is not None:
76 self.connection.close()
77 self.connection = None
Run Code Online (Sandbox Code Playgroud)
除此之外,我缺乏想法。
最后我切换回 Apache + mod_python(除了这个之外,我在使用 fcgi 时还遇到了其他随机错误),现在一切都很好并且稳定。
这个问题仍然悬而未决。如果以后有人遇到这个问题并解决了,可以在这里记录解决方案以供将来参考。:)
| 归档时间: |
|
| 查看次数: |
10155 次 |
| 最近记录: |