memo

2016-04-20

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 機能で満たすことができる。

  • --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