25

fcgi を使用して接続された nginx の背後で django インスタンスを実行しています (manage.py runfcgi コマンドを使用)。コードはメモリに読み込まれるため、django fcgi プロセスを強制終了して再起動しないと新しいコードをリロードできず、ライブ Web サイトが中断されます。再起動自体は非常に高速です。しかし、最初に fcgi プロセスを強制終了すると、一部のユーザーのアクションが中断されてしまい、良くありません。中断を引き起こさずに新しいコードをリロードするにはどうすればよいか疑問に思っています。アドバイスをいただければ幸いです。

4

5 に答える 5

16

そこで私は先に進み、Martin の提案を実装しました。これが私が思いついたbashスクリプトです。

pid_file=/path/to/pidfile
port_file=/path/to/port_file
old_pid=`cat $pid_file`

if [[ -f $port_file ]]; then
    last_port=`cat $port_file`
    port_to_use=$(($last_port + 1))
else
    port_to_use=8000
fi

# Reset so me don't go up forever
if [[ $port_to_use -gt 8999 ]]; then
    port_to_use=8000
fi

sed -i "s/$old_port/$port_to_use/g" /path/to/nginx.conf

python manage.py runfcgi host=127.0.0.1 port=$port_to_use maxchildren=5 maxspare=5 minspare=2 method=prefork pidfile=$pid_file

echo $port_to_use > $port_file

kill -HUP `cat /var/run/nginx.pid`

echo "Sleeping for 5 seconds"
sleep 5s

echo "Killing old processes on $last_port, pid $old_pid"
kill $old_pid
于 2009-06-05T17:16:19.377 に答える
10

この問題の解決策を探しているときに、このページに出くわしました。他のすべてが失敗したので、私はソースコードを調べました:)

解決策ははるかに簡単なようです。Django fcgiサーバーはflupを使用します。これは、HUP信号を適切な方法で処理します。つまり、正常にシャットダウンします。したがって、あなたがしなければならないのは、次のことだけです。

  1. HUPシグナルをfcgiサーバーに送信します(runserverのpidfile =引数が役立ちます)

  2. 少し待ちます(flupでは子供が10秒間処理できるので、さらに2、3秒待ちます。15は適切な数値のようです)

  3. 何かがブロックした場合に備えて、KILLシグナルをfcgiサーバーに送信しました

  4. サーバーを再起動します

それでおしまい。

于 2009-07-21T21:59:37.283 に答える
3

FastCGI の代わりにスポーンを使用できます

http://www.eflorenzano.com/blog/post/spawning-django/

于 2009-01-17T10:15:26.403 に答える
2

私たちはついにこれに対する適切な解決策を見つけました!

http://rambleon.usebox.net/post/3279121000/how-to-gracefully-restart-django-running-fastcgi

最初に HUP シグナルを送信して再起動を知らせます。次に、Flup はすべての子に対してこれを行います。

  1. 非アクティブな子を停止するソケットを閉じます
  2. INT信号を送る
  3. 10秒待つ
  4. KILL シグナルを送信します

すべての子がなくなると、新しい子が始まります。

これは、 flup がステップ2を実行するときに子がリクエストを処理している場合、サーバーが で停止しKeyboardInterrupt、ユーザーに 500 エラーを与えることを除いて、ほとんど常に機能します。

解決策は、SIGINT ハンドラーをインストールすることです。詳細については、上記のページを参照してください。SIGINT を無視するだけでも、プロセスが終了するまでに 10 秒かかります。これは、ほとんどの要求に対して十分です。

于 2011-02-14T10:55:29.750 に答える