Я пытаюсь перевести мое веб-приложение на Django в рабочую конфигурацию развертывания, и, потратив кучу времени, пытаясь заставить его работать под lighttpd / fastcgi, не могу обойти эту проблему.Когда клиент входит в систему в первый раз, он получает большой дамп данных с сервера, который разбивается на несколько кусков размером ~ 1 МБ, которые отправляются обратно в формате 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
Я действительно выдергиваю волосы, пытаясь понять, почему это происходит (чего не происходит, когдазапуск Django в режиме ./manage.py runserver
).Следующие вещи, которые я пробовал, не дали никакого эффекта:
Уменьшение размера чанка с 1 МБ до 256 КБ.Несмотря на то, что усечение обычно происходит при отметке 600–900 КБ, я все еще получал усечения при размере фрагмента 256 КБ.
Установка значений minspare
и maxchildren
на Джанго runfgci
очень высоко, так что вокруг будет висеть множество запасных нитей.
Установка maxchildren
на 1, чтобы была только одна резьба.
Переключение между режимом сокета UNIX и режимом TCP / IP для соединения fastcgi между lighttpd и Django.
Я много гуглил для этого, но не смог найти ничего, чтоказалось, что исправление для Django (любая помощь, казалось, была вокруг настройки PHP).
Моя настройка:
OSX 10.6.4
Python 2.6.1 (система)
lighttpd установлен из Macports (1.4.26_1 + ssl)
flupустановлен с последней версии Python egg на веб-сайте flup (пробовал стабильную версию 1.0.2 и последнюю версию 1.0.3)
Django 1.2.1 установлен из tarball на сайте Django
Блок FastCGI в моей конфигурации lighttpd:
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
)
)
)
Команда runfcgi
, которую я использую для запуска Djangoв настоящее время:
./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, и перспектива перехода на другую конфигурацию веб-сервера я не ожидаю ...
Заранее благодарен за любую помощь.
Редактировать: Дополнительная информация
Я нашел эту страницу на светлых форумах с указаниемчто это может быть вина Джанго ... в этом случае это был тот сбой PHP.Я проверил материал на стороне Django и обнаружил, что даже после усечения поток Python, отправивший усеченный ответ, все равно будет работать после этого и будет обслуживать последующие запросы, поэтому создается впечатление, что поток не прерывается потоком, попавшим в исключениеи вылетает.
Я хотел выяснить, был ли здесь виноват 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 отправляет TCP FIN
в Django, который, вероятно, вызывает прерывание соединения, и именно так вы получаете усечение.
На первый взгляд кажется, что это ошибка Lighttpd, поскольку он выглядит так, как будто отключается, прежде чем должен… хотя я не уверен, что он этого не делает, потому что он получил некоторые плохие данные от Django, на которые он реагирует отключением.