Sudo restart projectname
を発行するたびにgit pull Origin master
よりも良いものを探しています。これはDjangoプロジェクトへの私の最新の変更をプルダウンします。このrestart
コマンドは、Gstartサーバープロセスを開始/開始するために使用するUpstartに関連していると思います。
この再起動により、短時間の停止が発生します。 Gunicornがまだ再起動しているため、Webサーバー(nginx)にアクセスするユーザーには500が表示されます。実際、すぐに再起動するようですが、ページの読み込みには数秒かかります。
これをシームレスにする方法に関するアイデアはありますか?理想的には、git pull
を発行し、Gunicornを自動的にリロードしたいと思います。
正常にリロードするには、代わりにUpstartのreload
コマンドを使用する必要があります。例:
Sudo reload jobname
Initctl(Upstart) manpage によると、reload
はHUP
シグナルをプロセスに送信します。
reload JOB [KEY=VALUE]...
Sends the SIGHUP signal to running process of the named JOB instance.
...これはGunicornの場合、グレースフルリスタートをトリガーします( [〜#〜] faq [〜#〜] を参照)。
次のようにHUP
シグナルを使用してGunicornに正常にリロードするように指示できます。
kill -HUP <pid>
(詳細については [〜#〜] faq [〜#〜] を参照してください)
Supervisor を使用してGunicornサーバーを制御します。これにより、デプロイ後にGunicornをリロードするこの(少しハッキングな)方法を使用できます。
supervisorctl status gunicorn | sed "s/.*[pid ]\([0-9]\+\)\,.*/\1/" | xargs kill -HUP
明らかにpidof
またはps
で同様のことを達成できます。
これは実際には Fabric スクリプトから実行されるため、サーバーにログオンする必要さえありません。
スーパーバイザーを使用していない場合:ロブが言ったように、psでも動作します。
ps aux |grep gunicorn |grep projectname | awk '{ print $2 }' |xargs kill -HUP
systemdを使用してgunicornサービスを実行している場合、1行になります。
_systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$/\1/g p' | cut -f1 -d' ' | xargs kill -HUP
_
gunicorn docs は、ワーカーを正常にリロードする正しい方法は_kill -HUP <Main PID>
_を使用することであると言うため(ここで_<Main PID>
_はマスタープロセスのプロセスIDです)、マスターPIDを抽出しますsystemctlを使用して、_kill -HUP <Main PID>
_を実行します。
_systemctl status gunicorn
_
ここで、gunicorn
は_/etc/systemd/system/
_にあるサービスの名前です。
出力例:
_ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn
● gunicorn.service - Gunicorn server for yourproject.com
Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2017-11-04 19:16:24 UTC; 1h 15min ago
Main PID: 10673 (gunicorn)
CGroup: /system.slice/gunicorn.service
├─10673 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
├─11069 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
├─11070 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
└─11071 /home/ubuntu/site/venv/bin/python3 /home/ubuntu/site/venv/bin/gunicorn --workers 3 --bind unix:/tmp/yourproject.socket config.wsgi:application
Nov 04 20:27:04 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:27:04 +0000] [11047] [INFO] Booting worker with pid: 11047
Nov 04 20:27:04 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:27:04 +0000] [11048] [INFO] Booting worker with pid: 11048
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [10673] [INFO] Handling signal: hup
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [10673] [INFO] Hang up: Master
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11046] [INFO] Worker exiting (pid: 11046)
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11047] [INFO] Worker exiting (pid: 11047)
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11048] [INFO] Worker exiting (pid: 11048)
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11069] [INFO] Booting worker with pid: 11069
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11070] [INFO] Booting worker with pid: 11070
Nov 04 20:32:16 ip-10-4-12-247 gunicorn[10673]: [2017-11-04 20:32:16 +0000] [11071] [INFO] Booting worker with pid: 11071
_
sedコマンドは次のように機能します:_sed 's/<search this>/<replace with this>/g'
_
s
はsubstituteコマンドを意味し、g
は入力全体をグローバルに検索することを意味します 。-n
_フラグは、sednotにすべての行を印刷する(または実際には何も印刷しない)ように指示します。p
は、sedに一致した行を印刷するよう指示します。.*Main PID: \(.*\)$
を検索します。次の部分があります。_.*
_は、任意の文字(_.
_)に0回以上一致します(_*
_)。次に、_Main PID:
_に続いて任意の文字を検索し、ゼロ回以上繰り返します(_.*
_)。 _Main PID:
_- textの後のすべての文字をキャプチャするには、_.*
_を括弧で囲みます。括弧は、バックスラッシュ\(.*\)
でエスケープされます。 _$
_は行末を示します。\1
_で、これは最初にキャプチャされた文字セットを意味します。出力例:
_ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$/\1/g p'
10673 (gunicorn)
_
出力を cut にパイプします。 _cut -f1 -d' '
_は、つまり
-d
_は区切り文字を決定します。区切り文字は_-d
_の直後の文字です。区切り文字はスペースなので、引用符で囲みます。-f
_は、バイト単位ではなく区切り文字を使用して切り取りが行われることを意味し、_-f1
_はリストの最初の要素を取り出すことを意味します。出力例:
_ubuntu@ip-10-4-12-247:~$ systemctl status gunicorn | sed -n 's/.*Main PID: \(.*\)$/\1/g p' | cut -f1 -d' '
10673
_
xargs へのパイプは、左側のパイプから引数を指定してコマンドを実行することを意味します。 Main PIDのみをxargsにパイピングしているため、
_ systemctl status gunicorn-Django | sed -n 's/.*Main PID: \(.*\)$/\1/g p' | cut -f1 -d' ' | xargs kill -HUP
_
基本的には同じものです
_echo <Main PID > | xargs kill -HUP
_
に変換します
_kill -HUP <Main PID >
_
もう少し堅牢なソリューションは、_cut -f1 -d$'\n'
_の前に_grep -m1 ""
_または_cut -f1 -d' '
_を使用して、一致の最初の行だけを選択することです。ただし、_Main PID:
_に2つの一致がある状況を把握することはできません。
質問に対する直接的な答えではないかもしれませんが、gunicorn
Webサーバーを再起動する方法を探しているだけの人には、killall gunicorn
その後、コマンドを実行してgunicornを再度起動します。例えば:
killall gunicorn
gunicorn --bind 0.0.0.0:80 --reload app:app
注:killall gunicorn
はすべてのgunicornプロセスを即座に終了しますので、あなたが何をしているかを理解してください。
Gunicornをスーパーバイザーの下で実行しますが、これは混乱した場合にGunicornを正常にリロードすることがわかった最も簡単でクリーンな方法です。
Sudo pkill -HUP -f gunicorn.*master