Masteries

技術的なことや仕事に関することを書いていきます.

supervisorctlについて調べてみた

Supervisorの操作は, supervisordコマンドではなくsupervisorctlコマンドで行います(supervisordは, 単にSupervisorそのものを立ち上げるコマンドになっています).

supervisorctlを使ってコマンドを叩くことで, Supervisorそのものや, それが立ち上げている各種プロセスを操作することができます.

この辺り, 割とゆるふわに使っていた部分があったのですが, そりゃイカンよなというわけで, 多少本気を出して調べてみることにしました.

なお, 調査時に利用したSupervisorのバージョンは3.1.3です(記事投稿時の最新版).

supervisorctlのコマンド一覧

supervisorctlから使うことが出来るコマンドは, supervisorctl helpでその一覧を確認することができます.

# supervisorctl help

default commands (type help <topic>):
=====================================
add    clear  fg        open  quit    remove  restart   start   stop  update
avail  exit   maintail  pid   reload  reread  shutdown  status  tail  version

更に, 各コマンドの詳細については, supervisorctl help <command>で確認することが出来ます.

というわけで, 各コマンドについて詳しく見ていきましょう.

add

# supervisorctl help add
add <name> [...]        Activates any updates in config for process/group

読み込んだ設定ファイルにある, 新しく追加したプロセスやグループの名前を与えると, そのプロセスやグループをSupervisorのデーモンの管理対象として追加してくれるようです.

プロセスやグループの追加をした場合, 後述のrereadで設定ファイルを読み込んでから, 追加したプロセスやグループに対してaddをしてあげる, というのが主な使い方になりそうです.

ちなみに, 既にSupervisorのデーモンが管理済みのプロセスやグループの名前を与えると, 次のようなエラーが出ます.

# supervisorctl add app
ERROR: process group already active

avail

# supervisorctl help avail
avail                   Display all configured processes

Supervisorのデーモンが管理しているプロセスの詳細を確認出来るようです. 実際に(appworkerのプロセスが動いているサーバで)叩いてみるとこんな感じになりました.

# supervisorctl avail
app                              in use    auto      999:999
worker                           in use    auto      999:999

clear

任意のプロセスのログを消去してくれるようです.

# supervisorctl help clear
clear <name>            Clear a process' log files.
clear <name> <name>     Clear multiple process' log files
clear all               Clear all process' log files

exit

supervisorctlで開くSupervisorのシェルを閉じる為のコマンドみたいです. なので, supervisorctl exitとかしても, 特に何も起こりません.

# supervisorctl help exit
exit    Exit the supervisor shell.

fg

任意のプロセスをforegroundにすることができます. 例えばappというプロセスが動いているなら, supervisorctl fg appで, そのプロセスのログをforegroundにして, ログ等々を確認出来るようになります.

Ctrl+Cで抜けられる, と書かれているのですが, 手元の環境ではうまく動いてくれませんでした... tmux上で動かしているので, そいつが悪さをしているのかもしれませんが...

# supervisorctl help fg
fg <process>    Connect to a process in foreground mode
Press Ctrl+C to exit foreground

maintail

Supervisorそのもののログを確認できます. -fをつければ, tail -fのように最新の出力が適宜表示されるようになります.

# supervisorctl help maintail
maintail -f     Continuous tail of supervisor main log file (Ctrl-C to exit)
maintail -100   last 100 *bytes* of supervisord main log file
maintail        last 1600 *bytes* of supervisor main log file

open

他のSupervisorのプロセスにつなぐ為のコマンドのようです. 正直, このコマンドを使うシチュエーションがわからない...

他サーバのSupervisorに繋げる時とか, 複数のSupervisorを立ち上げている時に設定をいじくるSupervisorを切り替える時とか?

# supervisorctl help open
open <url>      Connect to a remote supervisord process.
                (for UNIX domain socket, use unix:///socket/path)

pid

Supervisorが管理しているプロセスのPIDを表示してくれます.

# supervisorctl help pid
pid                     Get the PID of supervisord.
pid <name>              Get the PID of a single child process by name.
pid all                 Get the PID of every child process, one per line.

例えば, こんな感じ.

# supervisorctl pid all
5217
5218

quit

exitと同じっぽい.

# supervisorctl help quit
quit    Exit the supervisor shell.

reload

Supervisorのデーモンを立ち上げ直します(リスタート). その際設定ファイルが読み込まれるので, 変更があればそれが適用された上で各プロセスが起動されます.

# supervisorctl help reload
reload          Restart the remote supervisord.

remove

現在Supervisorが読み込み済みの設定ファイルから, 一時的に指定したプロセスやグループに関する設定を削除します(*.iniなどの, 実際に設定が書かれているファイルには影響は及びません).

言い方を変えると, 「任意のプロセスやグループを, 一時的にSupervisorのデーモンの管理下から外す」という感じでしょうか.

# supervisorctl help remove
remove <name> [...]     Removes process/group from active config

ちなみに, removeする際はそのプロセスやグループは停止している必要があります. 停止していないと, 次のようなエラーが出ます.

# supervisorctl remove worker
ERROR: process/group still running: worker

再度, Supervisorのデーモンの管理対象にしたい場合は, 前述のaddで追加してあげると良いでしょう.

reread

Supervisorの設定ファイルを再読み込みします. 「再読込する」だけなので, この段階では変更した設定は各プロセスやグループに適用されません. 適用したい場合, 後述のrestartaddなどで適用してあげましょう.

# supervisorctl help reread
reread                  Reload the daemon's configuration files

restart

指定したプロセスをリスタートします. その段階でrereadなどで読み込まれている設定変更については, このタイミングで適用されますが, そうでない設定変更は適用されません.

# supervisorctl help restart
restart <name>          Restart a process
restart <gname>:*       Restart all processes in a group
restart <name> <name>   Restart multiple processes or groups
restart all             Restart all processes

shutdonw

Supervisorのデーモンを落とします.

# supervisorctl help shutdown
shutdown        Shut the remote supervisord down.

start

指定したプロセスを開始します. restartと同じく, 設定変更をした場合は, 予めrereadで読み込んでおく必要があります.

# supervisorctl help start
start <name>            Start a process
start <gname>:*         Start all processes in a group
start <name> <name>     Start multiple processes or groups
start all               Start all processes

status

任意のプロセスの状況を確認することができます.

# supervisorctl help status
status <name>           Get status for a single process
status <gname>:*        Get status for all processes in a group
status <name> <name>    Get status for multiple named processes
status                  Get all process status info

こんな感じで, 各プロセスの状況, PID, 起動してからどれだけの時間が経過したかを見ることが出来ます.

# supervisorctl status
app                              RUNNING   pid 5217, uptime 0:58:07
worker                           RUNNING   pid 5605, uptime 0:05:15

stop

各プロセスを停止します. 停止したプロセスの再起動は, 前述したstartを使いましょう.

# supervisorctl help stop
stop <name>             Stop a process
stop <gname>:*          Stop all processes in a group
stop <name> <name>      Stop multiple processes or groups
stop all                Stop all processes

tail

任意のプロセスの標準出力/標準エラー出力を確認することができます. maintailのプロセス版, という感じです.

# supervisorctl help tail
tail [-f] <name> [stdout|stderr] (default stdout)
Ex:
tail -f <name>          Continuous tail of named process stdout
                        Ctrl-C to exit.
tail -100 <name>        last 100 *bytes* of process stdout
tail <name> stderr      last 1600 *bytes* of process stderr

update

設定ファイルを読み込み直した上で, 必要に応じてaddによる設定の適用や, removeによるプロセスの削除を行ってくれるコマンドです.

# supervisorctl help update
update                  Reload config and add/remove as necessary
update all              Reload config and add/remove as necessary
update <gname> [...]    Update specific groups

version

最後のコマンド. いわゆるバージョンを出してくれるやつです.

# supervisorctl help version
version                 Show the version of the remote supervisord process

まとめ

設定ファイルを書き換えた場合, updateを叩けば設定ファイルの読み込みと適用を同時に行ってくれるので楽そうです.

# supervisorctl update

なお, 設定の適用時にはSupervisorのデーモンが管理しているプロセスも一旦落ちて, そこから立ち上げ直す形になるようです.

ちなみにreloadでも, 設定ファイルの読み込みと適用は実施できますが, updateの場合は設定に変更があったプロセスのみ再起動が実施されますが, reloadの場合は一旦Supervisorのデーモンそのものが落ちてしまうので, Supervisorで管理している全プロセスが(設定変更の有無に関わらず)再起動されてしまいます.

意図しないプロセスの再起動が実施されないように, updateを使った方が良さそうな気がします.

Supevisorの動きを理解するコツ

「Supervisorが設定ファイルを読み込んでいる(キャッシュしている)」という所が理解できれば, 各コマンドの動きは理解出来そうです.

通常, restart等すれば, 設定ファイルを読み込みなおした上で再起動してくれそうな感じがします. ただSupervisor(のデーモン)は起動時に設定ファイルを読み込んで, それをキャッシュしていて常にその設定ファイルを使うようになっている訳ですね. なので, 設定ファイルを書き換えた後に, それを読み込み直さずにrestartをすると, 「アレ, 変更が適用されていない...?」となる訳です.

「設定の読み込み」と「プロセスの操作」を分離して考えるのが, Supervisorの動き(操作)を理解する上での1つのコツになるのかな, と思いました.

オマケ: supervisorctlコマンド早見表

コマンド 効果
reread 設定ファイルの読み込み
restart プロセスの再起動(読み込み済みの設定が適用)
update reread + 設定変更があったプロセスのみrestart
start プロセスの起動(読み込み済みの設定が適用)
stop プロセスの停止
reload Supervisorのデーモンの再起動(デーモン起動時に設定ファイルを読み込み直す)
add Supervisorのデーモンの管理対象を追加
remove Supervisorのデーモンの管理対象から一時的に削除