У меня есть сайт 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.