Назад | Перейти на главную страницу

Apache, mod_wsgi, Django - странные 500 ошибок

У меня есть сайт Django, который большую часть времени работает хорошо, использование памяти стабильно, и мне бы не пришлось беспокоиться, если бы не какие-то странные проблемы, которые были редкими до вчерашнего дня и заставляли сайт отключаться всю прошлую ночь.

Конфигурация:

Я получаю трассировки:

[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 для ротации журналов, я «перенес» logging.WatchedFileHandler из Python 2.6 в проект, который находится в apps/py26_logging/handlers.py, но я предполагаю, что это не WatchedFileHandler, который вызывает это, и что он страдает только от более общей проблемы - потому что в 95% случаев он работает идеально.

В любом случае, перезапуск Apache немедленно устраняет проблему (до следующего раза, конечно).

ServerDensity, который я использую для мониторинга сервера, показывает стабильное использование памяти (плоская линия) с не менее 500 МБ свободной памяти в любое время, количество процессов также стабильно, и в целом ничего необычного в статистике, когда мое приложение сходит с ума.

Я попытался воспроизвести проблему с ApacheBench, но мне не удалось отклонить ни один запрос, если я не использовал 100 одновременных запросов:

Уровень параллелизма: 100 Полных запросов: 10000 Неудачных запросов: 1 (Подключение: 0, Получение: 0, Длина: 1, Исключения: 0) Ошибки записи: 0 Ответов, отличных от 2xx: 1

Я не должен упоминать, что это выходило за рамки обычной нагрузки, а статистика ServerDensity сильно выросла.

Кто-нибудь из вас видит здесь знакомую картину?

Я могу просто прокомментировать IOError: sys.stdout access restricted by mod_wsgi ошибка. Что-то в вашем Django-приложении записывает что-то в sys.stdout который ограничен mod_wsgi. Обычно с sys.stdout в приложении WSGI. Вы могли бы использовать WSGIRestrictStdout Off в вашей глобальной конфигурации Apache (не vhost) в качестве повязки. Для постоянного и чистого решения избавьтесь от любых print или что пишет sys.stdout. Подробнее см. документация mod_wsgi.