pmanager
CPUの負荷を監視し、プロセスを管理します。
リポジトリ:https://github.com/miyagaw61/pmanager
Install
cargo
$ curl https://sh.rustup.rs -sSf | sh
$ source ~/.cargo/env
pmanager
$ cargo install --git https://github.com/miyagaw61/pmanager
Usage
$ pmanager [process-num] [start-command] [kill-command]
キューに溜まっているプロセスの数がprocess-numで指定した値未満であればstart-commandを実行し、以上であればkill-commandを実行します。
現在のキューに溜まっているプロセスの数はvmstat
コマンドで見れます。
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 4111788 238984 1789116 0 0 4 5 24 65 0 0 99 0 0
procsのrがその値になります。この例では3になっています。
cron用シェルスクリプトの作成
export PATH=$PATH:/usr/local/bin
pmanager 6 ~/pmanager_start.sh ~/pmanager_kill.sh
例として今回は https://github.com/miyagaw61/ManukaZeny のプロセスを監視してみましょう。
export PATH=$PATH:/home/miyagaw61/.cargo/bin
export PATH=$PATH:/home/miyagaw61/src/github.com/macchky/cpuminer
export RUSGIT_SLACK_URL=https://hooks.slack.com/services/hogehoge
export RUSGIT_SLACK_CHANNEL=@fugafuga
manukazeny start $HOME/json-file &
export PATH=$PATH:/home/miyagaw61/.cargo/bin
export PATH=$PATH:/home/miyagaw61/src/github.com/macchky/cpuminer
export RUSGIT_SLACK_URL=https://hooks.slack.com/services/hogehoge
export RUSGIT_SLACK_CHANNEL=@fugafuga
manukazeny stop
cronを設定
$ crontab -e
* * * * * for i in `seq 0 5 59`;do (sleep ${i}; ~/pmanager_cron.sh) & done;
今回は5秒間隔で監視しています。
seq
の第二引数(今回の例での5
の部分)を変えることで、監視頻度を調整できます。
/tmp/pmanager.tmpのセット
pmanagerは、/tmp/pmanager.tmpというファイルで状態を管理しています。
start-commandが実行されていない状態(管理したいプロセスが終了してある状態)で次のコマンドを実行します。
$ echo -n killed > /tmp/pmanager.tmp
改行が入ってはいけないので、-n
オプションを付けることに注意してください。
現在のr(キューに溜まっているプロセスの数)がpmanager_cron.shに記述されているpmanagerの第一引数よりも少なくなったら、自動的にstart-commandで指定されている$HOME/pmanager_start.shが実行されます。
vmstatを見てみましょう。
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 4112140 239356 1789164 0 0 4 5 25 65 1 0 99 0 0
r=3です。
今回の例ではpmanagerの第一引数は6に設定してあるため、ManukaZenyが自動で開始しているはずです(/tmp/pmanager.tmpもstartedがセットされているはずです)。
$ cat /tmp/pmanager.sh
started
rを増やすために、手動でもう一つManukaZenyを立ち上げてみましょう。
$ ~/pmanager_start.sh
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
5 0 0 4106292 239464 1789196 0 0 4 5 25 65 1 0 99 0 0
惜しいですね。
もう一つ追加で立ち上げてしまいましょう。
$ ~/pmanager_start.sh
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
7 0 0 4097652 239524 1789312 0 0 4 5 25 65 1 0 99 0 0
6以上になりました。
すると、5秒以内に~/pmanager_kill.shが実行され、全てのManukaZenyが終了するはずです。
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 4119136 239736 1789184 0 0 4 5 25 65 1 0 99 0 0
$ cat /tmp/pmanager.sh
killed
そしてrが急激に減り、それを検知したpmanagerが一つだけManukaZenyを起動します(一度だけpmanager_start.shを実行します)。
$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 4111756 239624 1789232 0 0 4 5 25 65 1 0 99 0 0
$ cat /tmp/pmanager.tmp
started
実装予定の機能
複数のプロセスを管理
/tmp/pmanager.tmpで管理しているので、一つのプロセスしか管理できません。
管理ファイルを指定したプロセスごとに作成することで、同時に複数のプロセスを管理できるようにします。
同一process-numを指定した複数のプロセスを管理
設定したプロセスリストなどを作成しておき、複数のプロセスが同時に閾値に達した際に、リスト中からランダムで一つを終了させる.
cronの自動設定
SIGKILL, SIGINT, SIGSTOPなどのよく使うを終了コマンドとし、自動で設定してくれる機能.
cgroups
cgroupsと連携できたらします。
現在は終了コマンドをこちらで作成することしかできませんが、cgroupsを使って動的に実行中のプロセスのリソース制限を変更できるようにします(現在のままでもcgroupsの設定を書き換えるスクリプトを開始コマンドと終了コマンドで指定したらこれは可能ですが、それを自動化します)。
etcd
etcdでプロセスの終了イベントを設定
vmstatをn秒ごとに実行し、負荷をチェックする
この時のnはユーザが設定できるようにしていると良い
tmpfs
tmpfsでプロセスIDを保持しておく
inotify
よくわからない