gunicorn syncワーカーの全体像メモ
gunicornとは?
Gunicornは、PythonのWeb Server Gateway Interface(WSGI)を実装するHTTPサーバーである
https://ja.wikipedia.org/wiki/Gunicorn
対象読者
・gunicorn syncワーカーをざっくり把握したい人
・APサーバーが好きな人
はじめに
先日、全く知見がなかったgunicorn周りの不具合調査をする機会がありました。
その際に、gunicornの包括的な内容の日本語記事が見当たらず理解に苦労したので、個人的に重要だった点を書き留めておきます。
この記事で書かないこと
・gunicornの具体的な使い方
・syncワーカーって何って話
前提
- gunicorn: 20.0.4
- ワーカータイプ: syncタイプ
でのお話
基本設計
gunicornのsyncワーカータイプでは、マルチプロセス - preforkモデルを採用している。
つまり、masterプロセス(親プロセス)が、ワーカー(子プロセス)をフォークし、ワーカーが直に1リクエストづつ処理する。
root@2bb4dr5e9dae:/usr/src/app# gunicorn wsgi:application -w 3 --bind 0.0.0.0:8000
root@2bb4dr5e9dae:/usr/src/app# ps auxf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 5492 3200 pts/0 Ss+ 18:30 0:00 gunicorn wsgi:application -w 3 -t 100 --bind 0.0.0.0:8000
root 109 0.0 0.0 28992 22912 pts/0 S+ 18:30 0:03 /usr/local/bin/python /usr/local/bin/gunicorn wsgi:application -w 3 -t 100 --bind 0.0.0.0:8000
root 9953 2.7 0.7 1146564 176672 pts/0 Sl+ 19:17 0:27 \_ /usr/local/bin/python /usr/local/bin/gunicorn wsgi:application -w 3 -t 100 --bind 0.0.0.0:8000
root 9954 2.8 0.7 1146568 176676 pts/0 Sl+ 19:17 0:29 \_ /usr/local/bin/python /usr/local/bin/gunicorn wsgi:application -w 3 -t 100 --bind 0.0.0.0:8000
また、preforkなので、ワーカーはサーバー起動直後に全て作成されselect状態となる。
起動後は特に操作しない限りワーカーは増えたり/減ったりしない。
プロセス/ワーカーの操作
masterプロセスにシグナルを送ることでワーカーの操作ができる。
ex, TTINでワーカーを+1増やす
root@2bb4dr5e9dae:/usr/src/app# kill -TTIN 109
root@2bb4dr5e9dae:/usr/src/app# pgrep gunicorn
109
9953
10263
10264
ワーカーをkillすると、masterプロセスが検知してワーカーを作成し直す
root@2bb4dr5e9dae:/usr/src/app# kill -9 9954
root@2bb4dr5e9dae:/usr/src/app# pgrep gunicorn
109
9953
10263
起動オプション
チューニング等で使った起動オプション
-
--max-requests
INT
ワーカーごとに、リクエストをN数捌いたら、ワーカー(子プロセス)を再起動させるオプション。
再起動することでメモリが解放されるため、--max_requests_jitter
とセットで、緩めのメモリリーク対策などにも使える。
-
--timeout
INT
ワーカーが捌くリクエストごとのタイムアウト設定。あまりに長いとワーカーが枯渇してリクエスト詰まったりするので注意
実装としては、timeoutするとワーカーにSIGABRTシグナルが送られるよう。参考
-
--backlog
INT
(ワーカーが不足しリクエストが詰まった場合などで)、待機させられるリクエストの数。
ちなみに、実際に待機中のリクエスト数を取得/監視する方法はgunicornとしては用意していないようだった。参考
-
--reload
INT
アプリケーションのソースコードの変更を監視して、ワーカーをダウンタイムなく再起動(入れ替え)する。詳細
ローカル開発で使用したりします
graceful restartする方法
ダウンタイムなしでrestartかけたい場合は、masterプロセスに対し、HUPシグナルを送ればよい。
masterプロセスが、新しいワーカーを立ち上げ、古いワーカーをgracefulにシャットダウンしていく。
root@2bb4dr5e9dae:/usr/src/app# kill -HUP 117
参考
Discussion