Я запускаю Django за nginx за допомогою FastCGI. Я виявив, що в деяких відповідях, що надсилаються клієнту, випадкові пошкодження даних трапляються в середині відповідей (це може бути пару сотень байт в середині).
На даний момент я звузив це до помилки або в обробнику FastCGI nginx, або в обробнику Django FastCGI (тобто, мабуть, помилка в потоці), оскільки ця проблема ніколи не виникає, коли я запускаю сервер Django в автономному (тобто runserver
) режимі. Це відбувається лише в режимі FastCGI.
Інші цікаві тенденції:
Це, як правило, відбувається в більшій кількості реакцій. Коли клієнт входить у перший раз, йому надсилається купа шматів розміром 1 Мб для синхронізації їх із сервером БД. Після першої синхронізації відповіді значно менші (зазвичай це кілька кБ одночасно). Здається, що корупція завжди трапляється на тих шматочках розміром 1 МБ, які були надіслані на старті.
Це трапляється частіше, коли клієнт підключений до сервера через локальну мережу (тобто з низькою затримкою, високою пропускною здатністю). Це змушує мене думати, що існує якийсь стан перегонів у nginx або flup, який посилюється збільшенням швидкості передачі даних.
Зараз мені довелося обійти це питання, додавши додатковий дайджест SHA1 у заголовок відповіді та отримавши клієнт відхилити відповіді, коли заголовок не відповідає контрольній сумі тіла, але це своєрідне жахливе рішення.
Хто-небудь ще відчував щось подібне, чи є якісь вказівки щодо того, як визначити, чи винен тут флуп або 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)
EDIT: У відповідь на коментар Єжика шлях коду, який збирає відповідь, виглядає таким чином (відредагований для лаконічності):
# 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
Я не думаю, що неможливо, що довжина вмісту є помилковою на основі цього, і AFAIK не може позначати об'єкт Django HttpResponse як явно бінарний на відміну від тексту. Крім того, оскільки проблема трапляється лише з перервами, я не думаю, що це пояснює це інакше, імовірно, ви б бачили її при кожному запиті.
EDIT @ionelmc: Вам потрібно встановити довжину вмісту в Django - 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