uWSGIで利用できるオプションとその説明
- uWSGIは設定できるオプションが多いが公式サイトの説明がシンプルすぎてわからなくなるので、個人的に調べて内容を記載する。
ドキュメント
環境
- CentOS Linux release 7.9.2009 (Core)
- apach(2.4.6-97)
- python(3.6.8)
- uwsgi(2.0.20)
- Flask(2.0.3)
- mod_proxy_uwsgi(2.0.18)
uWSGIのインストール
- すでにuWSGIがインストールされている場合は念のため一度アンインストールする
pcreとpcre-develを入れてるのはlog-routeを利用する場合にpcre-develを入れてからuWSGIをインストールしないと
!!! no internal routing support, rebuild with pcre support !!!
のエラーが表示されlog-route機能が利用出来ないCentOS 7の場合
yum install pcre pcre-devel pip install uwsgi -I --no-cache-dir
- Ubuntuの場合
apt-get install libpcre3 libpcre3-dev pip install uwsgi -I --no-cache-dir
uwsgitopを利用する
- apacheのserver statusの様にサーバの動作状態を確認するためにuwsgitopを利用する
- uwsgitop
https://github.com/xrmx/uwsgitop
- uwsgitop
# python3 -m pip install uwsgitop
設定変更の参考
英語だけれどもuWSGIの設定について詳しく記載されている
uwsgiに設定するオプション
- uWSGI --helpで設定できるオプションの一覧が取得できるが量が多すぎる
設定内容の誤りをチェックする
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
strict | strict = true | 設定ファイルに記載できるオプションは、uWSGIがオプションとして認識できるもののみとし、strictを有効にした場合は認識できないオプションが記載されている場合はエラーでuWSGIが起動しなくなる typoを防げる。 独自のプレースホルダーが使えなくなる?(要調査) |
strict |
need-app | need-app = true | 実行するアプリケーションに問題があった場合uWSGIを起動しない デフォルトではアプリは起動するが500エラーを返すので有効にするのを推奨 |
need-app |
パフォーマンスの監視
- uwsgitopでstatsに指定したファイルを指定して現在のprocessの状態とthreadの状態を確認することができる
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
stats | stats = /var/log/uwsig.socket | パフォーマンス監視用の統計データを出力 | stats |
memory-report | memory-report = true | メモリーの使用量を出力? | memory-report |
便利そうなオプション
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
vacuum | vacuum = true | uWSGIが起動時に作成したファイル(ソケットやPIDのファイルなど)をuWSGIの終了時に自動的に削除する |
vacuum |
chmod-socket | chmod-socket = 666 | http-socket, socketオプショと併用する socketファイルのアクセス権限を変更する |
chmod-socket |
chown-socket | chown-socket = uwsgi_user | http-socket, socketオプショと併用する socketファイルの所有者を変更する |
chown-socket |
起動時に関係するオプション
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
chdir | chdir = /home/uwsgi_user/api | uWSGIが起動し、アプリケーションをロードする前にカレントディレクトリを移動する | chdir |
chdir2 | chdir2 = /home/uwsgi_user/api | uWSGIが起動し、アプリケーションをロードしたあとで、カレントディレクトリを移動する | chdir2 |
single-interpreter | single-interpreter = true | プロセス毎に一つのアプリケーションを利用する | single-interpreter PythonエージェントとuWSGIウェブサーバー |
die-on-term | die-on-term = true | SIGTERMを受けた時にプロセスを終了する デフォルトではプロセスが再起動してuWSGIは終了しない |
die-on-term What is –die-on-term? |
wsgi-file | wsgi-file = /home/uwsgi_user/api/app.py | 起動するアプリケーションのファイルを指定する | wsgi-file |
callable | callable = app 例としてFlaskの場合 from flask import Flask app = Flask(__name__) とした場合は、appを指定する |
起動するアプリケーションのオブジェクトを指定する | callable |
gid | gid = uwsgi_group | 起動するグループIDを指定する | gid |
uid | uid = uwsgi_user | 起動するユーザーIDを指定する | uid |
待ち受ける方式に関するオプション
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
http | http = 127.0.0.1:8080 | httpで指定されたアドレスとポート番号で起動する http-socketを利用する方がパフォーマンスが良い 環境によるので要パフォーマンス調査 |
http |
http-socket | http-socket = 127.0.0.1:8080 | http-socketで指定されたアドレスとポート番号で起動する processes = 1でtouch-reloadしてもエラーがクライアントへ返らない |
http |
socket | socket = /home/uwsgi_user/api/app.sock socket = 127.0.0.0:8080 |
socketで指定されたファイルまたはipアドレス:ポート番号のいずれかの方法で指定する ファイル名で指定する場合でapacheと連携する場合、apacheのバージョンが2.4.9以上が必要 |
socket |
各々の待受方式でベンチマークを行った結果
- apache → uwsgi → app.py実行した結果
- process=1, threads = 1での結果(環境によってすごく数値が変わるので参考程度)
方式 | abテストの結果 | uwsgiに直接http接続が可能か |
---|---|---|
http | Requests per second: 1119.57 [#/sec] (mean) | 可 |
socket(ip:port形式) | Requests per second: 1297.07 [#/sec] (mean) | 不可 |
http-socket | Requests per second: 1471.42 [#/sec] (mean) | 不可 |
socket(file形式) | Requests per second: 1522.14 [#/sec] (mean) | 不可 |
パフォーマンスに直接関係しそうなオプション
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
master | master = true | wokerのプロセスが終了した場合に自動的にwokerを再起動してくれる uWSGI内蔵のPerfork + マルチスレッドで動作する |
master |
enable-threads | enable-threads = ture | threadを有効にする enable-threads = true とした場合は threads = 1を設定したのと同じ効果がある |
enable-threads |
processes | processes = 4 | 利用するプロセス数 processesとworkersはどちらも名称は異なるが同一の設定 |
processes |
workers | workers = 4 | 利用するプロセス数 processesとworkersはどちらも名称は異なるが同一の設定 |
workers |
threads | threads = 15 | 利用するスレッド数 threadsを設定すると enable-threads = trueも設定される |
threads |
thunder-lock | thunder-lock = true | Linuxの場合有効にすることを推奨 | thunder-lock Serializing accept(), AKA Thundering Herd, AKA the Zeeg Problem |
ugreen | ugreen = true | OSのスレッド機構を利用せずに非同期にスレッドを切り替える機構を有効にする またgreenletよりもパフォーマンスに優れているが、メモリの消費が多い 環境にもよると思うが有効にしても特になにかが変わったように見えなかった |
ugreen uGreen – uWSGI Green Threads |
オプション設定不可 | OSのスレッド機構を利用せずに非同期にスレッドを切り替える機構を有効にする パフォーマンスはugreenより劣るがメモリの消費が少ない オプションが見つからずエラーとなる |
greenlet uGreen – uWSGI Green Threads |
ワーカーの再起動に関するオプション
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
max-requests | max-requests = 100 | 指定された回数のリクエストを処理したらwokerを再起動する | max-requests |
|
オプション設定不可 | max-requestsで指定された回数でwokerが再起動すると同じタイミングでworkerが再起動するので、タイミングをずらすために使用するとあるが、strict modeで起動するとオプションが見つからずエラーとなる エラーになる原因は以下を参考 あなたの使ってるuWSGI、本当にmax-requests-delta効いてますか? uWSGIのmax-requets-delta、マジで効いていない 現在のバージョン(uwsgi(2.0.20))では無効なオプションとなる |
max-requests-delta |
max-worker-lifetime | max-woker-lifetime = 60 | 指定された秒数が経過したらworkerを再起動する | max-worker-lifetime |
reload-on-rss | reload-on-rss = 2048 | 指定されたバイト数以上のメモリが利用されている場合wokerを再起動する | reload-on-rss |
worker-reload-mercy | worker-reload-mercy = 60 | workerがリロードやシャットダウンにかかる時間(秒) | worker-reload-mercy |
アプリケーションのリロードに関するオプション
- リロードに関する解説
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
touch-reload | touch-reload = /home/uwsgi_user/api/uwsig.touch 上記のファイルを更新するとworkerが再起動する |
Preforkモード(親プロセスをForkしてWorkerを作成するモード) リロードされる時にuWSGIの起動オプションも再読込される |
touch-reload |
lazy-apps | lazy-app = true | Preforkと違いWorker毎にアプリケーションをロードする | lazy-apps Standard (default/boring) graceful reload (aka SIGHUP) |
touch-workers-reload | touch-workers-reload = /home/uwsgi_user/api/uwsig.touch | lazy-appsと併用する インスタンス全体のWorkerの同時再起動を避けることができる touch-reloadと比べて特別メリットがない |
touch-workers-reload Workers reloading in lazy-apps mode |
touch-chain-reload | touch-chain-reload = /home/uwsgi_user/api/uwsig.touch | lazy-appsと併用する 一度に一つのWorkerを再起動するので再起動を行う際の待ち時間を減らすことができる また、Workerの再起動を順番に行うのでサーバに負荷がかからない ただし、それなりに多くのWorkerがないとあまり恩恵が受けられない |
touch-chain-reload Chain reloading (lazy apps) |
Zerg mode | よくわからない | よくわからない | Zerg mode 1 Zerg mode 2 |
リロードされる範囲
オプション | uWSGIのオプション変更 | 備考欄 |
---|---|---|
touch-reload | 変更可 | リロードにかかる時間が長い |
touch-workers-reload | 不可 | processの再起動のみなのでtouch-reloadよりは早い |
touch-chain-reload | 不可 | processの再起動を順番に行う |
Zerg mode |
ロガー
- ログ関係は設定の種類が多くてとても分かり辛い
- ロガーの設定方法は2種類ある(logtoとlogger)
- logto
- iniファイルで指定されたファイルへログの内容を出力するlogtoをベースにした機能
- logger
- iniファイルで指定された指定の場所(file, socket, syslogなど 詳細はLoggingを参考)へログの内容を出力するloggerをベースにした機能
- logto
logto
- ログの基本設定
- 記録される内容はオプションは変わっても同じ
- ログ出力に関するオプションを設定しない場合uWSGIの起動時のログ、アクセスログ、エラー内容が記録される
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
logto | logto = /home/uwsgi_user/api/access_log | uWSGIの起動時のログ、アクセスログ、エラーログが記録される | |
logto2 | logto2 = /home/uwsgi_user/api/access_log | 特権を剥奪してからログの記録を行う 他の動作はlogtoと同等 |
|
daemonize | daemonize = /home/uwsgi_user/api/access_log | uwsgi uwsgi.iniの様に起動したときに通常はコンソールがコマンド事項状態で止まるが、daemozineを有効にしている場合はuwsgi uwsgi.iniの実行後すぐにコンソールに戻ってきてuwsgiはバッググラウンドで実行するようになる<br<記録されるログはlogtoと同じ | |
daemonize2 | daemonize2 = /home/uwsgi_user/api/access_log | アプリケーションの起動後にバックグラウンド動作に移る uWSGIの起動時のログは記録れずコンソールに表示される、起動時のログが記録されない以外はlogtoと同じ内容が記録される ファイルをtouchして再起動した時は起動時のログも残る daemonizeと使い分けるメリットが良くわからない |
- ログ出力に関するオプション設定
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
disable-logging | disable-logging = true | 有効にした場合logtoで指定されたファイルへアクセスログを記録しない apacheとかnginxと連携している場合uWSGI側のアクセスログは不要だと思うのでdisable-logging = trueとしても問題ないと思う |
|
log-4xx | log-4xx = true | disable-logging = trueの場合に400エラーをlogtoに指定したファイルへ記録する 未設定の場合ログには400エラーは記録されない |
|
log-5xx | log-5xx = true | log-400 = trueと同じく500エラーをログに記録するようにするのかと思ったらtrueでもfalseでも関係なくlogtoで指定したファイルへエラーが記録されるので、設定する意味がないかもしれない |
logger
- ログに記録する内容をファイルだけでなく別の場所へ記録することができる
- loggerに記録される内容はlogtoと同じく、uWSGIの起動時のログ、アクセスログ、エラー内容が記録される
- log-routeがうまく働かない時はログに!!! no internal routing support, rebuild with pcre support !!!が出ていないか確認してください。
上記の文字が出ている場合はuWSGIのインストールを見てpcre-develを入れてから再度uWSGIを起動する
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
logger | logger = file:/home/uwsgi_user/api/access_log | 記録される内容はlogtoと同じ 複数回設定することができ、複数回指定した場合は設定されたすべての設定先にログが記録される |
|
req-logger | req-logger = file:/home/uwsgi_user/api/access_log logger = file:/home/uwsgi_user/api/error_log 約10Mでログローテートする場合 file:logfile=/home/uwsgi_user/api/access_log,maxsize=1000000 |
loggerと同時に設定する req-loggerを設定した場合アクセスログはreq-loggerに指定したファイルへ記録され、uWSGIの起動時のログ、エラー内容についてはloggerのファイルへ記録される 少し書き方を変えるとログローテートもできる |
|
log-route | logger = internalservererror file:/tmp/errors log-route = internalservererror (HTTP/1.\d 500) |
loggerと同時に設定する log-routeに設定された正規表現と一致するログをloggerに設定した場所へ振り分ける 公式サイトのサンプルを転機 log-routeに記載する正規表現はログファイルに記載される内容と一致する条件を書くこと 例えばログに [2022-08-07 21:40:11,780] ERROR in app: Exception on の様に記載されるのであれば logger = internalservererror file:/tmp/errors log-route = internalservererror ERROR in app の様に記載すると一致する行はloggerに指定されたファイルへ記録され、その他のlogggerには記録されなくなる uWSGIの起動時のログに記載される内容をlog-routeに設定すれば起動時のログだけを別ファイルに分離することもできる |
|
log-req-route | テストしていないので記載方法不明 | loggerと同時に設定する log-req-routeに設定された正規表現と一致するログをloggerに設定した場所へ振り分ける |
- ログ出力に関するオプション設定
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
disable-logging | disable-logging = true | logtoのログ出力に関するオプション設定でも書いたのと同様のオプション loggerと同時に設定した場合はreq-loggerを設定していてもアクセスログを記録することができなくなり、loggerで指定したファイルにもreq-loggerで設定したファイルにもアクセスログが記録されなくなる |
disable-logging |
log-4xx | log-4xx = true | logtoのログ出力に関するオプション設定でも書いたのと同様のオプション disable-logging = trueの場合でも400エラーをloggerに指定したファイルへ記録する req-loggerを指定している場合はreq-loggerに指定したファイルへ記録する 未設定の場合ログには400エラーは記録されない |
|
log-5xx | log-5xx = true | logtoのログ出力に関するオプション設定でも書いたのと同様のオプション trueでも、falseでも関係なくloggerに指定したファイルへエラー内容が記録される |
ログローテート
- logto, logto2, daemonize, daemonize2のファイルが対象
- uWSGIでログローテートをさせる場合現在のところファイルサイズを基準にログローテートをさせることしか出来ない。
日毎のログローテートは非対応。
オプション | サンプル | 内容 | ドキュメント |
---|---|---|---|
log-reopen | log-reopen = true | uWSGIが再起動した時にログを再読込する | log-reopen |
log-maxsize | log-maxsize=2000000 | ログファイルがここで定義されたサイズ(バイト)以上になった場合ログをログローテートする | log-maxsize |
logfile-chown | logfile-chown 引数なし |
uid, gidで指定したユーザーとグループでファイルを作成する こちらもlogfile-chmodと同じくdaemonize用? |
log-maxsize |
logfile-chmod | logfile-chmod = 777 | ログのアクセス権を変更する 設定しても反映されない daemonizeの時に反映されるような記事がある Nginx + uWSGI + Djangoのwebアプリケーション環境を作る (その4) |
log-maxsize |
touch-logreopen | touch-logreopen = /home/uwsgi_user/api/uwsgi_log.touch | uWSGIがログローテートを管理していない時にuWSGIに新しいログを読み込むように知らせるために利用する | touch-logreopen |
touch-logrotate | touch-logrotate = /home/uwsgi_user/api/uwsgi_log.touch 上記のファイルを更新するとログローテートされる |
uWSGIがログローテートを管理している時にuWSGIに強制的にログローテートを実行させる | touch-logrotate |
ロガーのフォーマット
ロガーの出力フォーマットを変更する
uwsgi default
[uwsgi] log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) %(uri) => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core))
log-format = %(addr) - %(user) [%(ltime)] "%(method) %(uri) %(proto)" %(status) %(size) "%(referer)" "%(uagent)"