pmanager 使い方

## 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用シェルスクリプトの作成

```:pmanager_cron.sh
export PATH=$PATH:/usr/local/bin
pmanager 6 ~/pmanager_start.sh ~/pmanager_kill.sh
```

例として今回は https://github.com/miyagaw61/ManukaZeny のプロセスを監視してみましょう。

```:pmanager_start.sh
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 &
```

```:pmanager_kill.sh
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
```

```:crontab
* * * * * 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

よくわからない