DjangoベースのWebアプリを動作するデプロイメント構成にしようとしていますが、lighttpd / fastcgiで動作させるために多くの時間を費やした後、この問題を乗り越えることができません。クライアントが初めてログインするとき、サーバーから大きなデータダンプを受け取ります。これは、JSONとして返送されるいくつかの〜1MBサイズのチャンクに分割されます。
時々、クライアントはチャンクの1つに対して切り捨てられた応答を受け取ります。このメッセージは、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
モードで実行しているときは起こりません)。以下は、私が試したが効果がなかったことです。
チャンクサイズを1MBから256Kに削減します。切り捨ては通常600K〜900Kのマーク付近で発生しますが、256Kのチャンクサイズでは切り捨てられます。
たくさんの予備のスレッドがぶら下がるように、Djangoのとの値を非常に高く設定し
minspare
ます。maxchildren
runfgci
maxchildren
スレッドが1つだけになるように1に設定します。lighttpdとDjango間のfastcgi接続のためにUNIXソケットモードとTCP/IPモードを切り替えます。
私はこのようなものをたくさんグーグルで検索しましたが、Djangoの修正と思われるものは見つかりませんでした(PHP設定の調整に関するヘルプがあったようです)。
私の設定は次のとおりです。
OSX 10.6.4
Python 2.6.1(システム)
Macportsからインストールされたlighttpd(1.4.26_1 + ssl)
flupWebサイトの最新のPythoneggからインストールされたflup(1.0.2安定版と最新の1.0.3開発版の両方を試しました)
DjangoWebサイトのtarballからインストールされたDjango1.2.1
私のlighttpd設定のFastCGIブロックは次のとおりです。
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のfcgiimplまたは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から送信され(8184バイトの場合は30082、さらに8184バイトの場合は30086)、その後、何らかの理由でエントリ30088にLighttpdがTCPFIN
をDjangoに送信します。これが、おそらく接続を終了させる原因です。切り捨てを取得する方法。
一見すると、これはLighttpdのせいのようです。これは、想定される前にシャットダウンしているように見えるためです...いくつかの悪いデータを受け取ったため、これを行っていないかどうかはわかりませんがシャットダウンして反応するDjangoから。