GlassFish v2.1のOS監視用カスタムMBeanを作る

感想おまちしてます!

楽天でのGlassFishの運用 by
寺田 佳央 (Yoshio Terada)
てので、楽天のエンジニアのインタビューが。
そこでも監視のことをが書かれている。

それがまさにわたしたちの欲しいものです。 ・・・中略・・・ アプリケーションサーバの何を監視すべきかなどの提案。

運用監視について、サブスクリプションを購入しない場合は、自分で考えなければならない。なければ作ればいいじゃない!か。

ちょうど、GlassFish Performance Advisor 的なもの、自作しようが昨日書かれていた!
これを参考に作ってみましょう。

その他参考になったサイト

スポンサーリンク

MBeanインタフェースの実装

インタフェースは必ず最後がMBeanにならないとだめ。?MXBeanでも登録はできたのでOKかも。

 package com.daipresents.gfmon;
public interface OSMonitorMBean {
public double getSystemLoadAverage();
public int getFreePhysicalMemoryInPercent();
public int getFreeSwapSpaceSizeInPercent();
}

おぎのさんのサンプルに合わせてcom.sun.management.OperatingSystemMXBeanでとれる値を定義。

カスタムMBeanの実装

作ったIFを実装する。注意しないといけないのがクラスの名前。OSMonitorMBeanというIFだからOSMonitorMBeanImplとかにしたら、以下のように怒られる。

MBean class com.daipresents.gfmon.OSMBeanImpl does not implement DynamicMBean, neither follows the Standard MBean conventions (javax.management.NotCompliantMBeanException: Class com.daipresents.gfmon.OSMBeanImpl is not a JMX compliant Standard MBean) nor the MXBean conventions (javax.management.NotCompliantMBeanException: com.daipresents.gfmon.OSMBeanImpl: Class com.daipresents.gfmon.OSMBeanImpl is not a JMX compliant MXBean)

クラス名にMBeanが入るとだめなのか?これでかなりの時間はまることに。

下のように、実装したクラスでは、メモリの利用量を計算している。IFを作らずにいきなり「OperatingSystemMXBean」をimplementsしても動いた。

 package com.daipresents.gfmon;
import java.lang.management.ManagementFactory;
import org.apache.log4j.Logger;
import com.sun.management.OperatingSystemMXBean;
public class OSMonitor implements OSMonitorMBean {
private Logger logger = Logger.getLogger(OSMonitor.class);
private OperatingSystemMXBean bean;
private long totalPhysicalMemorySize;
private long totalSwapSpaceSize;
public OSMonitor() {
super();
logger.info(OSMonitor.class.getName() + "Constractor.");
bean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
try {
totalPhysicalMemorySize = bean.getTotalPhysicalMemorySize();
totalSwapSpaceSize = bean.getTotalSwapSpaceSize();
} catch(Exception ex) {
throw new RuntimeException(ex);
}
}
@Override
public int getFreePhysicalMemoryInPercent() {
int percent =
(int) (100 * bean.getFreePhysicalMemorySize() / totalPhysicalMemorySize);
logger.info("FreePhysicalMemoryInPercent = " + percent);
return percent;
}
@Override
public int getFreeSwapSpaceSizeInPercent() {
int percent =
(int) (100 * bean.getFreePhysicalMemorySize() / totalSwapSpaceSize);
logger.info("FreeSwapSpaceSizeInPercent = " + percent);
return percent;
}
@Override
public double getSystemLoadAverage() {
double ave = bean.getSystemLoadAverage();
logger.info("SystemLoadAverage = " + ave);
return ave;
}
}

ソースをJarファイル(ここではgfmon.jar)に固めて準備は完了。
MBean内でログを出しているが、log4jはGF_ROOT/libとかに入れたくなかったので、ソースを落としてきて、jarファイルに含めた。

GlassFishへの登録

Chapter 14 Developing Custom MBeansにはMBeanの説明やasadminを使った登録方法が書いてある。
面倒なので管理コンソールから登録する。

001

カスタムMBeanから配備をクリック。

002Jarファイルを選択して、実装クラス名には実装したカスタムMBeanの完全修飾クラス名(com.daipresents.gfmon.OSMonitor)を入れる。
これでJarが「C:\fujihara\glassfish-v21\domains\domain1\applications\mbeans」に展開される。管理コンソールからのアップロードは上書きしてくれるだけなので、いらないクラスとかは消えずに残ってしまうので注意!!
消したいときは、管理コンソールから消したいカスタムBeanを消してから、mbeansフォルダにあるクラスも削除する。じゃないとGlassFishが起動しなくなる。。。怖い。。。
よって、更新したいときは全部消して再登録したほうがよさげだなー。

001 (1)次の名前には実装クラス名を入れた。おぎのさんのサンプルだとIF名(OSMonitorMBean)になっていたが、これだとIFを実装したクラスが複数あるとかぶるからこうした。

004配備されるとカスタムMBeanの一覧に表示される。

005確認のためjconsoleでのぞいてみる。JDKへのパスがとおっていればコマンドプロンプトでjconsoleと打てば起動するはず。
localhost:8686で、GlassFishの管理者ユーザ名とパスワード(admin/adminadmin)で接続する。

006ツリーをたどっていくと、作ったMBeanが表示されるはず。

jconsoleで確認したときにログも出ていた。MBeanはサーバ登録時や起動時にコンストラクタがよばれるみたいだ。

 2009-03-14 21:36:49,117  INFO com.daipresents.gfmon.OSMonitor - FreePhysicalMemoryInPercent = 26
2009-03-14 21:36:49,616  INFO com.daipresents.gfmon.OSMonitor - FreePhysicalMemoryInPercent = 26
2009-03-14 21:36:49,616  INFO com.daipresents.gfmon.OSMonitor - FreeSwapSpaceSizeInPercent = 12

コードはGoogle Codeにおいてます。