0

我试图让我的基于 Django 的 webapp 进入一个有效的部署配置,并且在花了很多时间试图让它在 lighttpd / fastcgi 下工作之后,无法解决这个问题。当客户端第一次登录时,他们会收到来自服务器的大量数据转储,这些转储数据被分成几个约 1MB 大小的块,以 JSON 的形式发回。

每隔一段时间,客户端就会收到一个对其中一个块的截断响应,我会在 lighttpd 日志中看到这条消息:

2010-09-14 23:25:01: (mod_fastcgi.c.2582) unexpected end-of-file (perhaps the fastcgi process died): pid: 0 socket: tcp:127.0.0.1:8000 
2010-09-14 23:25:01: (mod_fastcgi.c.3382) response already sent out, but backend returned error on socket: tcp:127.0.0.1:8000 for /myapp.fcgi?, terminating connection 

我真的很想弄清楚为什么会发生这种情况(在./manage.py runserver模式下运行 Django 时不会发生这种情况)。以下是我尝试过的没有效果的事情:

  • 将块大小从 1MB 减少到 256K。尽管截断通常发生在 600K - 900K 标记附近,但我仍然在 256K 块大小以下截断。

  • 将Django 的minspareand值设置得非常高,这样会有很多闲置线程。maxchildrenrunfgci

  • 设置maxchildren为 1 以便只有一个线程。

  • 针对 lighttpd 和 Django 之间的 fastcgi 连接在 UNIX 套接字模式和 TCP/IP 模式之间切换。

我在谷歌上搜索了很多东西,但找不到任何似乎可以修复 Django 的东西(任何帮助似乎都围绕着调整 PHP 设置)。

我的设置是:

  • OSX 10.6.4

  • Python 2.6.1(系统)

  • 从 Macports 安装的 lighttpd (1.4.26_1+ssl)

  • 从flup网站上最新的Python egg安装的flup(尝试了1.0.2 stable和最新的1.0.3 devel)

  • 从 Django 网站上的 tarball 安装的 Django 1.2.1

我的 lighttpd 配置中的 FastCGI 块是:

fastcgi.server             = ("/myapp.fcgi" =>
                               ("django" =>
                                 (
                                  #"socket" => lighttpd_base + "fcgi.sock",
                                  "host" => "127.0.0.1",
                                  "port" => 8000,
                                  "check-local" => "disable",
                                  "max-procs" => 1,
                                  "debug" => 1
                                 )
                               )
                             )

runfcgi我用来启动 Django的命令目前是:

./manage.py runfcgi daemonize=false debug=true host=127.0.0.1 port=8000 
method=threaded maxchildren=1

如果有人对如何阻止这种情况发生有任何见解,我们将不胜感激。如果我不能相对快速地解决这个问题,我将不得不放弃 lighttpd + fastcgi 并查看 Apache + mod_wsgi 或者可能是 nginx + fastcgi,并且进入另一个网络服务器配置的前景不是我期待的......

提前感谢您的帮助。

编辑:附加信息

我在轻量级论坛上发现了这个页面,表明这可能是 Django 的错……在那种情况下,PHP 崩溃了。我检查了我的 Django 端的东西,发现即使在截断之后,发送截断响应的 Python 线程仍然会在之后运行并为后续请求提供服务,所以看起来流没有被线程打破异常并崩溃。

我想弄清楚是 Django 的 fcgi impl 还是 Lighttpd 出了问题(因为这将决定迁移到 nginx + fastcgi 是否真的可以解决任何问题),所以我查看了 Wireshark 中的数据包跟踪. 截断之前发生的事情的简化日志如下:

No.     Time        Info
30082   233.411743  django > lighttpd [PSH, ACK] Seq=860241 Ack=869 Win=524280 Len=8184 TSV=417114153 TSER=417114153
30083   233.411749  lighttpd > django [ACK] Seq=869 Ack=868425 Win=524280 Len=0 TSV=417114153 TSER=417114153
30084   233.412235  django > lighttpd [PSH, ACK] Seq=868425 Ack=869 Win=524280 Len=8 TSV=417114153 TSER=417114153
30085   233.412250  lighttpd > django [ACK] Seq=869 Ack=868433 Win=524280 Len=0 TSV=417114153 TSER=417114153
30086   233.412615  django > lighttpd [PSH, ACK] Seq=868433 Ack=869 Win=524280 Len=8184 TSV=417114153 TSER=417114153
30087   233.412628  lighttpd > django [ACK] Seq=869 Ack=876617 Win=524280 Len=0 TSV=417114153 TSER=417114153
30088   233.412723  lighttpd > django [FIN, ACK] Seq=869 Ack=876617 Win=524280 Len=0 TSV=417114153 TSER=417114153
30089   233.412734  django > lighttpd [ACK] Seq=876617 Ack=870 Win=524280 Len=0 TSV=417114153 TSER=417114153
30090   233.412740  [TCP Dup ACK 30088#1] lighttpd > django [ACK] Seq=870 Ack=876617 Win=524280 Len=0 TSV=417114153 TSER=417114153
30091   233.413051  django > lighttpd [PSH, ACK] Seq=876617 Ack=870 Win=524280 Len=8 TSV=417114153 TSER=417114153
30092   233.413070  lighttpd > django [RST] Seq=870 Win=0 Len=0

好的数据包在开始时来自 Django(30082 为 8184 字节,然后再次在 30086 为另一个 8184 字节),然后由于某种原因在条目 30088 处 Lighttpd 向FINDjango 发送了一个 TCP,这可能是导致连接终止的原因,这就是你如何得到截断。

从表面上看,这似乎是 Lighttpd 的错,因为它看起来像是在它应该关闭之前关闭了东西......虽然我不确定它没有这样做,因为它收到了一些坏数据来自 Django,它通过关闭来做出反应。

4

2 回答 2

1

对于它的价值,我最终确实跳船到 nginx 并且一切似乎都运行良好,所以我怀疑这是 lighttpd 的错,而不是 Django 中的错误 fcgi impl 似乎是有根据的。

我实际上发现 nginx 的设置比 lighttpd 容易得多,更不用说你可以安装一个包含 lighttpd 在这里遇到的 SSL-break 错误的 nginx 的 macport (port install nginx +ssl) 。

于 2010-09-16T12:22:44.353 回答
0

您确定您没有其他东西已经在端口 8000 上进行侦听吗?按照惯例,该端口通常用于 HTTP 服务器,并且在其上运行 FASTCGI 进程是个坏主意。建议您在 8xxx 范围附近使用其他端口。

于 2010-09-15T03:50:38.707 回答