楽天でのGlassFishの運用 by
寺田 佳央 (Yoshio Terada)てので、楽天のエンジニアのインタビューが。
そこでも監視のことをが書かれている。
それがまさにわたしたちの欲しいものです。 ・・・中略・・・ アプリケーションサーバの何を監視すべきかなどの提案。
運用監視について、サブスクリプションを購入しない場合は、自分で考えなければならない。なければ作ればいいじゃない!か。
ちょうど、GlassFish Performance Advisor 的なもの、自作しようが昨日書かれていた!
これを参考に作ってみましょう。
その他参考になったサイト
- GlassFish Project – Self Management – Example rule and related code
- Using Custom MBeans to Extend the GlassFish Administration System
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を使った登録方法が書いてある。
面倒なので管理コンソールから登録する。

カスタムMBeanから配備をクリック。
Jarファイルを選択して、実装クラス名には実装したカスタムMBeanの完全修飾クラス名(com.daipresents.gfmon.OSMonitor)を入れる。
これでJarが「C:\fujihara\glassfish-v21\domains\domain1\applications\mbeans」に展開される。管理コンソールからのアップロードは上書きしてくれるだけなので、いらないクラスとかは消えずに残ってしまうので注意!!
消したいときは、管理コンソールから消したいカスタムBeanを消してから、mbeansフォルダにあるクラスも削除する。じゃないとGlassFishが起動しなくなる。。。怖い。。。
よって、更新したいときは全部消して再登録したほうがよさげだなー。
次の名前には実装クラス名を入れた。おぎのさんのサンプルだとIF名(OSMonitorMBean)になっていたが、これだとIFを実装したクラスが複数あるとかぶるからこうした。
配備されるとカスタムMBeanの一覧に表示される。
確認のためjconsoleでのぞいてみる。JDKへのパスがとおっていればコマンドプロンプトでjconsoleと打てば起動するはず。
localhost:8686で、GlassFishの管理者ユーザ名とパスワード(admin/adminadmin)で接続する。
ツリーをたどっていくと、作った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においてます。