Lighttpd + FastCGI + django: risposta troncata inviato al cliente a causa di EOF inaspettato
Domanda
Sto cercando di ottenere la mia webapp basato Django in una configurazione di distribuzione di lavoro, e dopo aver trascorso un po 'di tempo a cercare di farlo funzionare sotto lighttpd / FastCGI, non riesco a superare questo problema. Quando un client i registri in per la prima volta, ricevono una grande discarica di dati dal server, che è rotto in blocchi diversi dimensioni ~ 1MB che vengono inviati indietro come JSON.
Ogni tanto, il cliente riceverà una risposta troncata per uno dei pezzi, che vedrà questo messaggio nei registri 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
Sono davvero tirando fuori i miei capelli cercando di capire il motivo per cui questo accade (cosa che non avviene durante l'esecuzione in modalità di Django ./manage.py runserver
). Di seguito sono cose che ho provato che hanno avuto alcun effetto:
-
La riduzione della dimensione del blocco da 1MB a 256K. Anche se il troncamento di solito accade in tutto il 600K -. Marchio 900K, ho ancora avuto troncamenti sotto la dimensione 256K blocco
-
Impostazione dei valori
minspare
emaxchildren
sulrunfgci
di Django molto alto in modo che ci saranno un sacco di discussioni pezzi in giro. -
Impostazione
maxchildren
1 in modo che v'è un solo filo. -
La commutazione tra modalità di socket UNIX e modalità TCP / IP per la connessione tra fastcgi lighttpd e Django.
Googled molto per questa roba, ma non riusciva a trovare qualcosa che sembrava essere una difficoltà per Django (qualsiasi aiuto sembrava essere intorno tweaking impostazioni PHP).
La mia configurazione è:
-
OSX 10.6.4
-
Python 2.6.1 (sistema)
-
lighttpd installato da MacPorts (1.4.26_1 + ssl)
-
flup installato da ultimo uovo Python sul sito flup (provato sia 1.0.2 stabile e più recente 1.0.3 devel)
-
Django 1.2.1 installato dal tarball sul sito Django
Il blocco FastCGI nel mio config 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
)
)
)
Il comando runfcgi
che sto usando per iniziare Django è attualmente:
./manage.py runfcgi daemonize=false debug=true host=127.0.0.1 port=8000
method=threaded maxchildren=1
Se qualcuno ha qualche comprensione di come evitare che questo succeda, l'aiuto sarebbe molto apprezzato. Se non riesco a risolvere questo in tempi relativamente brevi dovrò abbandonare lighttpd + FastCGI e guardare Apache + mod_wsgi o forse nginx + FastCGI, e la prospettiva di andare in un altro server web di configurazione non è qualcosa che vedo l'ora di ...
Grazie in anticipo per qualsiasi aiuto.
Modifica: Altre Informazioni
questa pagina sui forum le luminose che indicano che potrebbe essere colpa di Django .. . in quel caso si trattava che PHP stava arrestando. Ho controllato la mia roba Django-side e ho scoperto che anche dopo un troncamento, il filo di Python che ha inviato la risposta troncata sarebbe ancora in esecuzione dopo e servirebbe richieste successive, così sembra che il flusso non è stato rotto dal filo colpendo un'eccezione e schiantarsi fuori.
ho voluto capire se o non era impl fcgi di Django o Lighttpd che era colpa qui (perché che determinerà se o non si muove per nginx + FastCGI sarebbe in realtà risolvere nulla), così ho preso uno sguardo al pacchetto tracciare in Wireshark. Il registro semplificata di ciò che accade appena prima di un troncamento è qui sotto:
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
Buoni pacchetti provengono dal Django all'inizio (30082 per 8184 byte, e poi di nuovo a 30086 per altri 8184 byte) e quindi all'ingresso 30088 per qualche ragione Lighttpd invia un FIN
TCP a Django che presumibilmente è ciò che provoca il collegamento per terminare ed è così che si ottiene il troncamento.
Sulla faccia di esso, sembra che questo è colpa di Lighttpd, dal momento che sembra che si sta spegnendo le cose prima che si suppone che ... anche se non sono sicuro che non sta facendo questo perché ha ricevuto alcuni dati errati da Django a cui si reagisce chiudendo down.
Soluzione
Per quello che vale, ho fatto alla fine finiscono per nave salto a nginx e tutto sembra funzionare bene, quindi il mio sospetto che era colpa di lighttpd piuttosto che un impl fcgi buggy in Django sembra essere stato fondato.
In realtà ho trovato la messa a punto di nginx molto più facile di lighttpd, per non parlare che è possibile installare un macport di nginx (porto installare nginx + SSL) che non contenere il bug SSL-breaking che soffre lighttpd da qui .
Altri suggerimenti
Sei sicuro di non avere qualcos'altro già in ascolto sulla porta 8000. Questa porta è di solito utilizzato per i server HTTP per convenzione e sarebbe cattiva idea per eseguire processo FastCGI su di esso. Suggerisco di utilizzare una porta diversa dove vicino gamma 8xxx.