Я использую Django за nginx, используя FastCGI. Я обнаружил, что в некоторых ответах, отправляемых клиенту, в середине ответов происходит случайное повреждение данных (может быть пара сотен байтов или около того в середине).
На данный момент я сузил это до того, чтобы быть либо ошибкой в обработчике FastCGI в nginx, либо обработчиком FastCGI в Django (то есть, вероятно, ошибкой в flop), поскольку эта проблема никогда не возникает, когда я запускаю сервер Django в автономном (то есть runserver
) режиме. Это происходит только в режиме FastCGI.
Другие интересные тенденции:
Это имеет тенденцию происходить при больших ответах. Когда клиент входит в систему в первый раз, ему отправляется куча блоков по 1 МБ, чтобы синхронизировать их с БД сервера. После этой первой синхронизации ответы становятся намного меньше (обычно несколько килобайт за раз). Похоже, что коррупция всегда происходит в тех 1-мегабайтных фрагментах, которые отправляются с самого начала
Это происходит чаще, когда клиент подключен к серверу через локальную сеть (то есть соединение с низкой задержкой и высокой пропускной способностью). Это заставляет меня думать, что в nginx или flup есть какое-то состояние гонки, которое усугубляется увеличением скорости передачи данных.
Прямо сейчас мне пришлось обойти это, поместив дополнительный дайджест SHA1 в заголовок ответа, и заставить клиента отклонять ответы, когда заголовок не соответствует контрольной сумме тела, но это своего рода ужасное решение.
Кто-нибудь еще сталкивался с чем-то подобным, или есть какие-либо указания относительно того, как определить, является ли это ошибкой flup или nginx, чтобы я мог сообщить об ошибке в соответствующую команду?
Заранее благодарю за любую помощь.
Примечание: я также опубликовал похожую ошибку в lighttpd + FastCGI + Django некоторое время назад здесь: /programming/3714489/lighttpd-fastcgi-django-truncated-response-sent-to-client-due-to - неожиданно ... хотя это не одно и то же (усечение по сравнению с повреждением), все начинает казаться, что распространенным виновником является flup / Django, а не веб-сервер ..
Изменить: я должен также отметить, что моя среда:
OSX 10.6.6 на Mac Mini
Python 2.6.1 (система)
Django 1.3 (из официального архива)
Flup 1.0.2 (из яйца Python на сайте Flup)
nginx + ssl 1.0.0 (из Macports)
РЕДАКТИРОВАТЬ: В ответ на комментарий Ежика путь кода, который собирает ответ выглядит (отредактировано для краткости):
# 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: Вы должны установить Content-Length в Django - nginx не устанавливает это для вас, как показано в примере ниже, как только я явно отключил установку Content-Length:
$ 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