我正在使用FastCGI在nginx后面运行Django。我发现在发送给客户端的某些响应中,响应的中间发生了随机数据损坏(中间可能有数百个字节左右)。
在这一点上,我将其范围缩小为Nginx的FastCGI处理程序或Django的FastCGI处理程序中的错误(即,可能是flup中的错误),因为当我在独立(即runserver
)模式下运行Django服务器时,永远不会发生此问题。它仅在FastCGI模式下发生。
其他有趣的趋势:
它倾向于在较大的响应上发生。客户端首次登录时,将向他们发送一堆1MB的块,以将其同步到服务器DB。第一次同步后,响应要小得多(通常一次只有几个KB)。损坏似乎总是发生在开始时发送的那些1MB数据块上。
当客户端通过LAN连接到服务器时(即低延迟,高带宽连接),这种情况会更经常发生。这使我认为Nginx或flup中存在某种竞争状况,而这种竞争状况会由于数据速率的提高而加剧。
现在,我不得不通过在响应头中放置一个额外的SHA1摘要来解决此问题,并让客户端拒绝响应头与主体校验和不匹配的响应,但这是一种可怕的解决方案。
是否有其他人经历过类似的事情,或者是否有任何指示如何确定是flup还是nginx在这里出了问题,所以我可以向相应的团队提交错误报告?
在此先感谢您的帮助。
注:我也张贴了类似的错误在lighttpd的FastCGI的+ + Django的一段时间回到这里:/programming/3714489/lighttpd-fastcgi-django-truncated-response-sent-to-client-due-to -意想不到的 ...即使这不是同一件事(截断还是损坏),它也开始看起来是罪魁祸首是flup / Django而不是Web服务器。
编辑:我还应该注意我的环境是:
Mac Mini上的OSX 10.6.6
Python 2.6.1(系统)
Django 1.3(来自官方tarball)
flup 1.0.2(来自flup网站上的Python egg)
nginx + SSL 1.0.0(来自Macports)
编辑:为响应Jerzyk的评论,汇编响应的代码路径如下所示(为简洁起见进行了编辑):
# This returns an objc NSData object, which is an array.array
# when pushed through the PyObjC bridge
ret = handler( request )
response = HttpResponse( ret )
response[ "Content-Length" ] = len( ret )
return response
我认为基于此的Content-Length不太可能是错误的,并且AFAIK无法将Django HttpResponse对象标记为显式二进制而不是文本。另外,由于该问题只是间歇性发生,因此我认为这不能解释该问题,否则您可能会在每次请求时看到它。
编辑@ionelmc:您必须在Django中设置Content-Length-一旦我禁用了显式设置Content-Length,nginx不会为您设置此内容,如以下示例所示:
$ curl -i http://localhost/io/ping
HTTP/1.1 200 OK
Server: nginx/1.0.0
Date: Thu, 23 Jun 2011 13:37:14 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
AKSJDHAKLSJDHKLJAHSD