Сбой FastCgi Хотите перехватить все исключения, но как?

У меня есть приложение django, работающее на apache с fastcgi (использует WSGIServer Flup).

Это настраивается через dispatch.fcgi, объединенное ниже:

#!/usr/bin/python

import sys, os

sys.path.insert(0, os.path.realpath('/usr/local/django_src/django'))

PROJECT_PATH=os.environ['PROJECT_PATH']

sys.path.insert(0, PROJECT_PATH)

os.chdir(PROJECT_PATH)

os.environ['DJANGO_SETTINGS_MODULE'] = "settings"

from django.core.servers.fastcgi import runfastcgi

runfastcgi(method="threaded",daemonize='false',)

Runfastcgi — это тот, кто выполняет работу, в конечном итоге запуская WSGIServer на WSGIHandler.

Иногда случается исключение, которое приводит к падению fastcgi.

РЕДАКТИРОВАТЬ: я не знаю, какая ошибка приводит к сбою fastcgi или даже сбой fastcgi. Я просто знаю, что иногда сайт падает - постоянно падает - пока я не перезагружу apache. Единственными ошибками, которые появляются в error.log, являются сломанная труба и неполные заголовки, перечисленные ниже.

Неполные заголовки:

примечание: я заменил конфиденциальную информацию или беспорядок на "..."

[Sat May 09 ...] [error] [client ...] (104)Connection reset by peer: FastCGI: comm with server ".../dispatch.fcgi" aborted: read failed
[Sat May 09 ...] [error] [client ...] FastCGI: incomplete headers (0 bytes) received from server ".../dispatch.fcgi"
[Sat May 09 ...] [error] [client ...] (32)Broken pipe: FastCGI: comm with server ".../dispatch.fcgi" aborted: write failed,

Сломанная труба:

примечание: это относится к сайту trac, а не к приложению django, но выглядит одинаково.

Unhandled exception in thread started by <bound method Connection.run of <trac.web._fcgi.Connection object at 0xb53d7c0c>>
Traceback (most recent call last):
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 654, in run
    self.process_input()
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 690, in process_input
    self._do_params(rec)
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 789, in _do_params
    self._start_request(req)
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 773, in _start_request
    req.run()
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 582, in run
    self._flush()
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 589, in _flush
    self.stdout.close()
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 348, in close
    self._conn.writeRecord(rec)
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 705, in writeRecord
    rec.write(self._sock)
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 542, in write
    self._sendall(sock, header)
  File "/usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 520, in _sendall
    sent = sock.send(data)
socket.error: (32, 'Broken pipe')

Я просмотрел /var/log/apache2/error.log, но не могу найти причину сбоя. У меня иногда возникают проблемы с подкачкой памяти, но я думаю, что это другое. (Пожалуйста, извините мое невежество. Я хочу научиться лучше реализовывать и отлаживать администрирование сервера.)

Я хотел бы обернуть runfastcgi с помощью try/except. Каков наилучший способ обработки случайных исключений (пока я не выясню фактическую причину (ы))?

Я считаю, что WSGIServer обрабатывает много запросов. Если я поймаю исключение, могу ли я повторно вызвать runfastcgi, не опасаясь бесконечного цикла? Должен ли я возвращать Error HttpRequest для оскорбительного запроса, вызывающего исключение? Я даже не знаю, как это сделать.

Я просматривал django/core/servers/fastcgi.py и django/core/handlers/wsgi.py и django/http/init.py.

Я не смог добиться прогресса в понимании стороны дела флопа.

Есть идеи или опыт, на котором я мог бы учиться?

Спасибо!


person Community    schedule 09.05.2009    source источник


Ответы (2)


Вероятно, это ошибка Flup. Когда клиентское соединение сервера, основанного на флопе, закрывается до того, как флюп отправляет данные, возникает исключение socket.error: (32, 'Broken pipe').

Попытка поймать исключение с помощью try catch вокруг runfastcgi не сработает. Просто потому, что исключение вызывается потоком.

Хорошо, я объясню, почему обертывание собственного кода в try catch не сработает. Если вы внимательно посмотрите на трассировку исключений, вы увидите, что первая инструкция в трассировке не является runfastcgi. Это потому, что исключение происходит в другом потоке. Если вы хотите поймать исключение, вам нужно обернуть любой из операторов, перечисленных в трассировке, в try/catch следующим образом:

# in file /usr/lib/python2.4/site-packages/Trac-0.12dev_r7715-py2.4.egg/trac/web/_fcgi.py", line 654, in run
try:
    self.process_input()
except socket.error:
    # ignore or print an error
    pass

Дело в том, что вы можете поймать ошибку, изменив код Flup. Но я не вижу в этом никакой пользы. Тем более, что это исключение кажется безобидным и для него уже есть патч.

person Nadia Alramli    schedule 09.05.2009
comment
Ok. Ошибка возникает из-за того, что клиент закрывает соединение до выполнения флопа. Однако это происходит, когда я просто захожу на главную страницу своего сайта. Похоже, что произошел сбой сервера или, по крайней мере, fastcgi, но это единственные ошибки, которые я вижу. Любые советы, как отладить это? - person ; 10.05.2009
comment
Вы пробовали применить патч, указанный в сообщении об ошибке? Это может решить вашу проблему. Является ли ошибка причиной сбоя запроса? или это просто отображается в журналах без заметных побочных эффектов? - person Nadia Alramli; 10.05.2009
comment
Я пытаюсь выяснить, являются ли сломанные трубы причиной или симптомом. хм ... думаю, я мог бы применить патч и посмотреть. Тем не менее, я бы предпочел узнать больше о том, как отлаживать или понимать ситуацию. не хочу гоняться за рискованными отвлекающими маневрами. - person ; 10.05.2009
comment
Хорошо, я добавил больше деталей в ответ, надеюсь, это прояснит ситуацию. - person Nadia Alramli; 10.05.2009

Сломанная труба обычно не возникает детерминировано. Вы получаете сообщение Broken pipe, если операция записи в канал или сокет завершается сбоем из-за того, что другой конец закрыл соединение. Поэтому, если ваш FastCGI получает Broken pipe, это означает, что веб-сервер слишком рано закрыл соединение. В некоторых случаях это не проблема, его можно молча игнорировать.

В качестве быстрого хака попробуйте поймать и проигнорировать socket.error с Broken pipe. Возможно, вам придется добавить пункт except: во многие другие места.

person pts    schedule 09.05.2009
comment
Еще много мест Спасибо за подсказку, но боюсь, я все еще учусь. Где? Я бы предпочел не исправлять django или flup. Я рад изменить dispatch.fcgi и свое собственное приложение django. - person ; 10.05.2009