uwsgi でアクセスがあるまで worker 起動を遅延 & アクセスが無くなったら worker を止めたい
目的: 単体ではそれほどアクセスが来ないようなアプリケーションを多数、一台のサーバー上で運用したい。
で、実際にアクセスがあるまでは worker の起動を遅延する & アクセスがなくなったら worker を停止、 という動作ができれば、おそらくこういうケースでネックになるであろうメモリ使用量を節約できるかなぁ、 という考え。
(その代わりに、アイドル時からの初回アクセス時には worker 起動分で処理時間が余計にかかるけど、そこは許容できるとする。)
uwsgi なら何かやたらと機能を持っているようなので、コイツで出来ないかどうか考えてみる。
作戦1: uwsgi の機能だけでやる
--cheap
オプションを指定することで、初回アクセスまで worker の起動を遅延できる--idle
オプションで秒数を指定することで、その時間アクセスが無ければ worker を停止できる
ということで、 uwsgi の機能だけで要件を満たすことができる。
実行例:
$ uwsgi --http :9000 --wsgi-file /path/to/myapp.py --idle 60 --cheap
作戦2: systemd の socket activation と組み合わせる
「実際にアクセスがあるまでは起動を遅延する」という部分は、 systemd の socket activation 機能で満たすことができる。
uwsgi は socket activation に対応している 。 (所定の環境変数が定義されている場合は、自動でその fd を使うようになっている。)
--idle
オプションに加えて--die-on-idle
を指定することで、アクセスがない場合に uwsgi 自体を停止することができる。
こちらはアイドル時には uwsgi プロセスが完全に停止するので、よりメモリの節約になるが、 その分初回アクセス時の起動コストは高くなる、といったところ。
設定例:
myapp.socket
:
[Unit]
Description=socket for my application
[Socket]
ListenStream=9000
myapp.service
:
[Unit]
Description=my application
[Service]
ExecStart=/usr/bin/uwsgi --protocol http --wsgi-file /path/to/myapp.py --idle 60 --die-on-idle
Restart=no