Я использую 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
источник
Ответы:
Есть ли у вас какая-либо директива кэширования nginx (bypass / no_cache) для ответов fastcgi?
В nginx '1.0.3 Changenotes исправлено повреждение ответа:
Источник: http://nginx.org/en/CHANGES (раздел 1.0.3.)
источник
Возможно, случайное повреждение происходит только в том случае, если выходные данные содержат хотя бы один символ UTF-8.
Длина содержимого и длина строки - это не одно и то же, потому что один символ UTF-8 может содержать от 2 до 5 байтов.
источник
Один из способов устранения неполадок в этом случае - это:
Как только вы обнаружите ошибку на стороне клиента (на основе sha1), перейдите к захвату сети, посмотрите на записанный (TCP) поток и попытайтесь выяснить, сгенерирована ли проблема nginx или она возникла (напрямую) из django ,
источник
У меня была очень похожая проблема, которая мучала меня до тех пор, пока у меня была эта установка. Как и вы, я использую FastCGI, Nginx и macOS, и обнаружил случайное повреждение в середине больших запросов (это было около 2% запросов от 1,5 МБ документа).
Я смог решить мою проблему, переключившись на сокеты Unix через TCP для соединения FastCGI между PHP-FPM (в моем случае) и Nginx. Я не знаю, какая часть головоломки ответственна за повреждение, но избегание внутреннего соединения TCP все-таки исправило.
источник