Сбои FastCgi - Хотите перехватить все исключения, но как? - PullRequest
0 голосов
/ 09 мая 2009

У меня есть приложение 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 попыткой / исключением. Каков наилучший способ обработки случайных исключений (пока я не выясню фактическую причину (ы))?

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

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

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

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

Спасибо!

Ответы [ 2 ]

3 голосов
/ 09 мая 2009

Это, вероятно, Flup bug . Когда клиентское соединение на основе сервера flup закрывается до того, как служба flup отправляет данные, возникает исключение socket.error: (32, 'Broken pipe').

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

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

# 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. Но я не вижу никакой пользы от этого. Особенно потому, что это исключение кажется безвредным и для него уже есть патч.

0 голосов
/ 10 мая 2009

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

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

...