Apache,mod_wsgi,Django – 奇怪的500错误

我有一个Django网站,大部分时间都运行良好,内存使用情况稳定,如果不是一些奇怪的问题,我不必担心,这些问题直到昨天才偶然发生,导致整个网站昨晚整个下载。

组态:

  • Debian Lenny
  • Apache 2.2 prefork
  • mod_wsgi 2.5
  • Python 2.5.2
  • Django 1.2.5

回溯我得到:

[error] mod_wsgi (pid=7390): Exception occurred within sys.exitfunc(). [error] Traceback (most recent call last): [error] File "/usr/lib/python2.5/atexit.py", line 24, in _run_exitfuncs [error] func(*targs, **kargs) [error] File "/usr/lib/python2.5/logging/__init__.py", line 1354, in shutdown [error] h.flush() [error] File "/usr/lib/python2.5/logging/__init__.py", line 731, in flush [error] self.stream.flush() [error] IOError: sys.stdout access restricted by mod_wsgi 

当我重新启动Apache或触摸.wsgi文件时,往往会生成上面的文件,所以我并不担心这一点。 以下是更有趣的:

 [error] [client ..] mod_wsgi (pid=8184): Exception occurred processing WSGI script '.../django.wsgi'. [error] [client ..] Traceback (most recent call last): [error] [client ..] File ".../django/core/handlers/wsgi.py", line 248, in __call__ [error] [client ..] response = self.get_response(request) [error] [client ..] File ".../django/core/handlers/base.py", line 140, in get_response [error] [client ..] receivers = signals.got_request_exception.send(sender=self.__class__, request=request) [error] [client ..] File "...django/dispatch/dispatcher.py", line 172, in send [error] [client ..] response = receiver(signal=self, sender=sender, **named) [error] [client ..] File "...django/db/transaction.py", line 299, in _commit_on_success [error] [client ..] res = func(*args, **kw) [error] [client ..] File ".../apps/utils/middleware.py", line 28, in exception_handler [error] [client ..] 'url': request.get_full_path() [error] [client ..] File "/usr/lib/python2.5/logging/__init__.py", line 1015, in error [error] [client ..] apply(self._log, (ERROR, msg, args), kwargs) [error] [client ..] File "/usr/lib/python2.5/logging/__init__.py", line 1101, in _log [error] [client ..] self.handle(record) [error] [client ..] File "/usr/lib/python2.5/logging/__init__.py", line 1111, in handle [error] [client ..] self.callHandlers(record) [error] [client ..] File "/usr/lib/python2.5/logging/__init__.py", line 1148, in callHandlers [error] [client ..] hdlr.handle(record) [error] [client ..] File "/usr/lib/python2.5/logging/__init__.py", line 655, in handle [error] [client ..] self.emit(record) [error] [client ..] File "../apps/py26_logging/handlers.py", line 394, in emit [error] [client ..] self.stream.flush() [error] [client ..] ValueError: I/O operation on closed file 

一个解释的话:因为我使用logrotate进行日志轮转,所以我将apps/py26_logging/handlers.py logging.WatchedFileHandler“backport”到放置在apps/py26_logging/handlers.py ,但是我的猜测是,它不是WatchedFileHandler这只是遭受更普遍的问题 – 因为95%的时间,它完美的作品。

无论如何,Apache重启立即解决问题(直到下一次当然)。

我使用服务器监控的ServerDensity显示了一个稳定的内存使用情况(扁平线),至less有500MB的可用内存,进程数量也是稳定的,而且当我的应用程序变得疯狂的时候,统计数据并没有什么不寻常的事情发生。

我试图用ApacheBench重现问题,但是我没有设法失败任何单个请求,除非我使用了100个同时的请求:

并发级别:100完成请求:10000失败请求:1(连接:0,接收:0,长度:1,例外:0)写入错误:0非2xx响应:1

我不必提及这是超出了通常的负载,ServerDensity统计数字猛增了很多。

你们有人在这里看到熟悉的模式吗?

我只能评论IOError: sys.stdout access restricted by mod_wsgi错误IOError: sys.stdout access restricted by mod_wsgi 。 Django-App中的某些东西将东西写入到受mod_wsgi限制的sys.stdout中。 在WSGI应用程序中,通常不会发生sys.stdout输出。 您可以在您的全局Apacheconfiguration(不是vhost)中使用WSGIRestrictStdout Off作为创可贴。 对于一个永久和干净的解决scheme,摆脱任何print或任何写入sys.stdout 。 有关更多详细信息,请参阅mod_wsgi文档 。