「数字を出力するコマンドを定期的に実行して、秒間の変化量を memcachedプロトコルで取れるサーバを書いた」で紹介した、derived。memcahcedプロトコルで外からアクセスするだけじゃなくて、GrowthForecastに直接ポストできたら便利だなと思ったので、構成見直してプラグインでデータの出力方法をカスタマイズできるようにした。
CPAN: https://metacpan.org/release/App-derived
github: https://github.com/kazeburo/App-derived
今まで
$ derived -i 10 --port 12306 cmdsfile
だったのが、
$ derived -i 10 -MMemcahced,port=12306 cmdsfile
と -M でプラグインを読み込むようになります。何もプラグインを指定しないと、Memcachedプラグインが読み込まれるので今までのオプションでも問題なく動きます。
GrowthForecastは
$ derived -i 60 -MGrowthForecast,api_uri=http://host/api/,service=foo,section=bar,persec=persec,interval=60 cmdsfile
のように指定すれば、1分毎にコマンドを実行して秒間の差分をGrowthForecastに投げる事ができます。
コンソールに出力するだけのプラグインもあります
$ derived -i 1 -MDumper,interval=1 cmdsfile
derivedを使ったJavaのヒープのモニタリング
これを使って某サービスのとあるJavaプロセスのヒープをGrowthForecast使ってグラフにしてみた。Javaなプロセスのヒープの簡単な統計は jstat というコマンドで取得できます。プロセス側のオプションを変更せずに使えるのがいいところ。
$ jstat -gcutil -h10 $pid 1000
S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 73.66 43.10 51.80 142 3.402 108 10.482 13.884
0.00 0.00 73.66 43.10 51.80 142 3.402 108 10.482 13.884
とりあえず取りたいのはOLD領域の使用率(解放できないメモリが溜まると100%に張り付く)と、FullGCの回数(メモリ不足になると回数が急増する)の2つ。
cmdsfileには
oldheap:/usr/local/java/bin/jstat -gcutil -h10 `pgrep -of 'foo.bar'` |tail -1|awk '{print $4*100}'
fullgc:/usr/local/java/bin/jstat -gcutil -h10 `pgrep -of 'foo.bar'` |tail -1|awk '{print $8*100}'
それぞれの数字を取得して、100倍にしている。これはGrowthForecastが小数をサポートしないためです。
そしてderivedを起動
derived \
-i 60 \
-MGrowthForecast,api_url=http://gf/api/,service=foo,section=bar,match_key=oldheap,prefix=${MYHOSTNAME}_,interval=60 \
-MGrowthForecast,api_url=http://gf/api/,service=foo,section=bar,match_key=fullgc,type=persec,prefix=${MYHOSTNAME}_,interval=60 \
/path/to/derived/cmdsfile
match_keyというGrowthForecastプラグインのオプションをつかって、上はoldheapの最新の値だけを送り、下はFullGCの秒間の差分をGrowthForecastに送ります。こんな感じで1つのプラグインを異なるオプションで複数指定する事もできたりします。
更新間隔はGrowthForecastなので1分で十分です。
そして出来たのがこんなグラフ。
元データで100倍しているので、GrowthForecast側で1/100にして表示しています。10m gc/secというのは1分間に1回程度はFullGCが動いているという感じですかね、丸められてしまっているので分かりにくいですが傾向は掴めそう。これを参考にサービスを安定させて、枕を高くして寝たい。
参考文献
Javaなサーバを見るときは、いつもここを参考にしてます