FastCgi崩溃 - 想要捕获所有异常,但如何?

时间:2009-05-09 18:00:25

标签: python django fastcgi wsgi flup

我有一个使用fastcgi在apache上运行的django应用程序(使用Flup的WSGIServer)。

这可以通过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是完成工作的人,最终在WSGIHandler上运行WSGIServer。

有时发生异常会导致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,但我似乎找不到崩溃的原因。我有时会遇到内存交换问题,但我认为这是不同的。 (请原谅我的无知。我愿意学习如何更好地实现和调试服务器管理员。)

我想用try / except包装runfastcgi。处理随机异常的最佳方法是什么(直到我找出实际原因)?

我相信WSGIServer会处理许多请求。如果我遇到异常,我可以重新调用runfastcgi而不用担心无限循环吗?我应该为违规的异常调用请求返回Error HttpRequest吗?我甚至不确定该怎么做。

我一直在浏览django / core / servers / fastcgi.py和django / core / handlers / wsgi.py和django / http / init .py

我无法在了解flup方面取得进展。

我可以从中学到什么想法或经验吗?

谢谢!

2 个答案:

答案 0 :(得分:3)

这可能是一个Flup bug。当flup完成发送数据之前关闭基于flup的服务器的客户端连接时,它会引发socket.error:(32,'Broken pipe')异常。

尝试通过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的代码来捕获错误。但我认为没有任何好处。特别是因为这个异常似乎是无害的,而且已经有了补丁。

答案 1 :(得分:0)

断管通常不会有确定性。如果管道或套接字上的写入操作失败,则会得到 Broken pipe ,因为另一端已关闭连接。因此,如果您的FastCGI获得 Broken pipe ,则意味着Web服务器已过早关闭连接。在某些情况下,这不是问题,可以默默忽略。

快速破解,尝试捕捉并忽略socket.errorBroken pipe。您可能需要在更多地方添加except:子句。