我正在尝试将基于Django的Web应用程序转换为可用的部署配置,并且在花费大量时间尝试使其在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的minspare
上的maxchildren
和runfgci
值设置得非常高,这样就会有很多备用线程。
将maxchildren
设置为1,以便只有一个帖子。
在UNIX套接字模式和TCP / IP模式之间切换,以实现lighttpd和Django之间的fastcgi连接。
我已经搜索了很多东西,但找不到任何似乎是Django的修复程序(任何帮助似乎都在调整PHP设置)。
我的设置是:
OSX 10.6.4
Python 2.6.1(系统)
从Macports安装的lighttpd(1.4.26_1 + ssl)
从flup网站上的最新Python蛋安装的flup(尝试了1.0.2稳定和最新的1.0.3开发)
在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
)
)
)
我用来启动Django的runfcgi
命令目前是:
./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,并且进入另一个webserver配置的前景不是我期待的......
提前感谢您的帮助。
修改:其他信息
我在轻松的论坛上发现this page表明它可能是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向Django发送TCP FIN
,这可能是是什么导致连接终止,这就是截断的方式。
从表面上看,似乎这是Lighttpd的错,因为看起来它在关闭事情之前应该关闭......虽然我不确定它是不是因为它收到了来自Django的一些不良数据,它通过关闭来做出反应。
答案 0 :(得分:1)
为了它的价值,我最终最终跳到了nginx并且一切似乎工作正常,所以我怀疑它是lighttpd的错,而不是Django中的一个错误的fcgi impl似乎是有充分根据的。
我实际上发现nginx的设置比lighttpd容易得多,更不用说你可以安装一个nportx的macport(端口安装nginx + ssl)不包含破解SSL的bug lighttpd遭受here。
答案 1 :(得分:0)
您确定没有其他东西已经在端口8000上侦听。该端口通常按惯例用于HTTP服务器,并且在其上运行FASTCGI进程是个坏主意。建议您在8xxx范围附近使用不同的端口。