Java向けの障害解析ツールHeapStatsをGlassFishに入れてみた
こちらで紹介されているJava向けの障害解析ツールHeapStatsが便利そうなので導入してみた。
環境はGlassFish3.1 + JDK7 + CentOS 6.3(32bit)
まずは、運用環境にrpmを使ってインストール.
wget http://icedtea.wildebeest.org/download/heapstats/heapstats-1.0.0/bin/agent/el6/i686/heapstats_agent-1.0.0-0.el6.i686.rpm sudo rpm -ihv heapstats_agent-1.0.0-0.el6.i686.rpm
Wikiにも記載があるとおりrpmで入れた場合は/etc/heapstats/heapstats.confに設定ファイルができる。今回はログの出力先を${DOMAIN}/logsに変更したかったので下記のように修正
diff ./heapstats.conf /etc/heapstats/heapstats.conf 5,7c5,7 < file=../logs/heapstats_snapshot.dat < heaplogfile=../logs/heapstats_log.csv < archivefile=../logs/heapstats_analyze.zip --- > file=heapstats_snapshot.dat > heaplogfile=heapstats_log.csv > archivefile=heapstats_analyze.zip
続いてGlassFishにHeapStatsの呼び出しを追加する。
管理コンソール等で「JVMの設定」 -> 「JVMオプション」 -> 「JVMオプションの追加」で下記のオプションを追加する。
-agentpath:/usr/lib/heapstats/libheapstats.so=/etc/heapstats/heapstats.conf
さて、これで仕込みはOKとGlassFishを再起動してみると...
立ち上がらないよ!
起動時に下記のようならエラーが出ていました。
[glassfish@webook glassfish]$ bin/asadmin start-domain ebooksearchDomain Waiting for ebooksearchDomain to start .Error starting domain ebooksearchDomain. The server exited prematurely with exit code 1. Before it died, it produced the following output: heapstats INFO: HeapStats 1.0.0 heapstats INFO: Supported processor features: None Error occurred during initialization of VM agent library failed to init: /usr/lib/heapstats/libheapstats.so heapstats WARN: Failure search library on memory. heapstats WARN: Failure getting symbol information. heapstats CRIT: Getting low level infomation failed!
はて、なんだろ。とりあえずlibheapstats.soでシンボル情報が無いって言われてるみたい。
heapstatsのソースコードの関連しそうな部分を眺めてみると下記のようにun.boot.library.pathという、なんとなくOracleJVM(Sun JVM)に依存しそうな記述を発見。
2090 bool oopUtilInitialize(jvmtiEnv *jvmti) { 2091 2092 /* Search symbol in libjvm. */ 2093 char *libPath = NULL; 2094 jvmti->GetSystemProperty("sun.boot.library.path", &libPath); 2095 try{ 2096 /* Create symbol finder instance. */ 2097 symFinder = new TSymbolFinder(); 2098 if(unlikely(!symFinder->loadLibrary(libPath))){ 2099 throw 0; 2100 }
実はOpenJDKを使ってたんだけど、OpenJDKを利用しないといけない明確な理由も無いので、OracleJDK7に切り替え。再起動したところ無事起動ー。
ログが下記のように出力されてれば動作は成功。
[glassfish@webook glassfish]$ ls -1 logs/h* logs/heapstats_log.csv logs/heapstats_snapshot.dat
れ
ちなみに現在出てるのはNomalモードのログ。障害時にはALLモードのログが出るみたい。明示的に出したいなら、SIGNAL2を下記のように飛ばせばOK。
kill -SIGUSR2 `ps ux|grep "glassfish.jar"|grep java|awk '{print $2}'`
これでheapstats_analyze130630190604.zipみたいな感じでログが出力されてればOK。
続いて解析の仕方。
出力されたheapstats_log.csvやheapstats_snapshot.datをローカルマシン等にコピーして
java -jar heapstats.jar
でクライアントを実行する。注意点として実行またはantのビルド時にjcommonとjfreechartが要求されること。
それぞれDLしてjarファイルをlib以下に置く必要がある。これは面倒だからivy + fat-jarに変更しておこうかなぁ。個人的にはmavenが楽で良いけど。
単にJMXで取る時と違って、メモリダンプも取れてるのはGood. 本番環境でもほぼ負荷がないということだし、とりあえず常に有効しておけばいいのかな。あと、クライアントでの解析の仕方が未だ慣れてないので、これは要勉強。
なんにしてもこの手のツールが整ってるのがJVM系の良いとこですね。
それでは、’Happy Hacking!
参考