Я пытаюсь привести свое веб-приложение на основе 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
в Django очень высокими, чтобы было много свободных потоков.Установка
maxchildren
в 1, чтобы был только один поток.Переключение между режимом сокета UNIX и режимом TCP / IP для соединения fastcgi между lighttpd и Django.
Я много искал в Google для этого, но не смог найти ничего, что казалось бы исправлением для 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 установлен из архива на сайте 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, и перспектива перехода в другую конфигурацию веб-сервера - это не то, чего я с нетерпением жду ...
Заранее благодарю за любую помощь.
Изменить: дополнительная информация
Я нашел эту страницу на светлых форумах, указывая, что это может быть вина Django ... в этом Дело было в том, что PHP давал сбой. Я проверил свой материал на стороне Django и обнаружил, что даже после усечения поток Python, который отправил усеченный ответ, все равно будет работать после этого и будет обслуживать последующие запросы, поэтому похоже, что поток не прерывается потоком, вызывающим исключение и вылетает.
Я хотел выяснить, виноват ли здесь Django 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, на который он реагирует завершением работы.