0

我有一个使用 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 而不必担心无限循环吗?我应该为有问题的异常调用请求返回一个错误 HttpRequest 吗?我什至不知道该怎么做。

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

我无法在理解 Flup 方面取得进展。

有我可以学习的想法或经验吗?

谢谢!

4

2 回答 2

3

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

试图通过 runfastcgi 周围的 try catch 来捕获异常是行不通的。仅仅因为异常是由线程引发的。

好的,我将解释为什么将您自己的代码包装在 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 的代码来捕获错误。但我看不出这有什么好处。特别是因为这个异常似乎是无害的,并且已经有一个补丁。

于 2009-05-09T18:37:04.980 回答
0

破损的管道通常不是确定性的。如果对管道或套接字的写操作由于另一端已关闭连接而失败,您将得到一个Broken pipe 。所以如果你的 FastCGI 得到一个Broken pipe,这意味着网络服务器过早地关闭连接。在某些情况下,这不是问题,可以默默地忽略它。

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

于 2009-05-09T21:36:13.723 回答