| Oracle® Fusion Middleware Oracle WebLogic Server JMXによるカスタム管理ユーティリティの開発 12c (12.2.1.1.0) E79368-01 |
|
![]() 前 |
![]() 次 |
この章の内容は以下のとおりです。
モニターするMBeanが通知を送信する場合は、MBeanにおける変更をリスニングするリスナー・オブジェクトを作成するか、MBeanを定期的にポーリングして、属性値が特定の方法で変更された場合にのみ通知を送信するモニターMBeanを作成するかを選択することができます。どちらの方法を選ぶかは、主に通知を受信する状況の複雑さによって決まります。
要件が単純な場合は、MBeanからリスナーに通知が送信され、変更が直ちに通知されるので、リスナーを直接MBeanに登録する方法が適しています。ただし、リスナーとオプショナルなフィルタ(javax.management.NotificationListenerおよびNotificationFilter)を実装するベース・クラスには、値をしきい値や他の値と比較する機能がほとんどありません(Java SE 7 API仕様のjavax.managementパッケージ(http://docs.oracle.com/javase/7/docs/api/javax/management/package-summary.html)を参照してください。)
通知の要件が複雑な場合や、MBean属性値の1つの変更に直接関連付けられない一連の変更をモニターする場合は、モニターMBeanを使用します。(Java SE 7 API仕様のjavax.management.monitorパッケージ(http://docs.oracle.com/javase/7/docs/api/javax/management/monitor/package-summary.html)を参照してください。)モニターMBeanには、データを比較して、特定の状況でのみ通知を送信するツールが豊富に用意されています。ただし、モニターは観察対象MBeanで属性値の変更を定期的にポーリングし、変更の通知は指定したポーリング間隔でのみ受けられます。
WebLogic Server JMXエージェントとWebLogic Server MBeanは、様々なタイプのイベントに応じて様々な型の通知オブジェクトを送信します。ほとんどのイベント・タイプは複数のMBeanをトリガーして、イベント・プロセスの様々な時点で通知を送信します。表7-1では、一般的なイベント・タイプについて説明し、通知をリスニングするためにJMXモニター・アプリケーションが登録すべき推奨MBeanを示しています。
注意:
各JMX通知オブジェクトには、ドット区切りの文字列を格納するTypeという属性があります。このType属性の説明と通知のオブジェクト型を混同しないようにしてください。
Type属性によって、通知の分類やフィルタ処理を行うことができます。たとえば、カスタムMBeanが通知を送信する場合、JMXの規約では、通知オブジェクトのType属性を、mycompany.myapp.valueIncreasedという企業名で始まる文字列に設定するように薦めています。
すべてのJMX通知オブジェクトはjavax.management.Notificationオブジェクト型を拡張します。JMXとWebLogic Serverではjavax.management.AttributeChangeNotificationなどの追加の通知オブジェクト型を定義しています。追加のオブジェクト型には、様々なタイプのイベントに適した特殊な情報が含まれています。(Java SE 7 API仕様に記載されたjavax.management.NotificationのNotificationサブクラス・リスト(http://docs.oracle.com/javase/7/docs/api/javax/management/Notification.html)を参照してください。)Oracle WebLogic Server Java APIリファレンスのweblogic.management.logging.WebLogicLogNotificationも参照してください。)
表7-1 イベント通知オブジェクト
| イベント | リスニングの推奨事項 |
|---|---|
WebLogic Serverインスタンスが起動する、停止する |
サーバーの起動または停止時に通知を受信するには、リスナーをドメイン・ランタイムMBeanサーバー内の各サーバーの ドメイン内の各サーバーには独自の このようなリスナーとフィルタの例については、「WebLogic Server MBeanからの通知のリスニング:主な手順」を参照してください。 注意: この推奨事項では、管理対象サーバーを起動する前にドメインの管理サーバーを起動することを前提としています。管理サーバーよりも前に管理対象サーバーを起動すると、管理対象サーバーの |
WebLogic Serverリソースが作成される、破棄される |
サーバーやJDBCデータ・ソースなどのリソースを作成するときに、WebLogic Serverはリソースの構成MBeanをMBeanサーバーに登録します。リソースを削除するときに、構成MBeanの登録を解除します。 Mbeanの登録と登録解除をリスニングするには、 型の通知を送信します。 編集MBeanサーバー内の ランタイムMBeanサーバーまたはドメイン・ランタイムMBeanサーバーでリスナーを登録した場合は、保留中の変更がドメインで正常にアクティブ化されたときにのみ通知を受信します。構成データのモニターにのみ関心があり、ランタイム統計のモニターには関心がない場合は、リスナーをランタイムMBeanサーバーにのみ登録します。「ベスト・プラクティス: MBeanサーバーの選択」を参照してください。 「例:構成MBeanの登録のリスニング」を参照してください。 |
WebLogic Serverリソースの構成が変更される |
すべての構成MBeanは、属性値が変わるときに この通知を受信するには、ドメイン・ランタイムMBeanサーバーまたはランタイムMBeanサーバー内のMBeanにリスナーを登録します(「ベスト・プラクティス: MBeanサーバーの選択」を参照)。 編集MBeanサーバー内のMBeanに登録した場合は、保留中のMBean階層が変更されたときに通知を受信します。 ランタイムMBeanサーバーまたはドメイン・ランタイムMBeanサーバーでリスナーを登録した場合は、保留中の変更がドメインで正常にアクティブ化されたときにのみ通知を受信します。構成データのモニターにのみ関心があり、ランタイム統計のモニターには関心がない場合は、リスナーをランタイムMBeanサーバーにのみ登録します。「ベスト・プラクティス: MBeanサーバーの選択」を参照してください。 |
WebLogic Serverリソースの実行時状態が変わる |
一部のランタイムMBeanは、属性値が変わると 実行時MBeanが通知を送信しない場合は、実行時MBeanをポーリングするモニターMBeanを作成できます。「モニターMBeanを使用した変更の観察: 主な手順」を参照してください。 |
WebLogic Serverリソースがログ・メッセージを送信する |
WebLogic Serverリソースがログ・メッセージを送信するとき、サーバーの ログ・メッセージの通知をリスニングするには、 WebLogic Serverリソースが生成するエラー・メッセージのリストについては、エラー・メッセージを参照してください。 詳細は、Oracle WebLogic Server Java APIリファレンスの |
WebLogic Server MBeanは、サービスやリソースの実行時状態に関する詳細な統計を提供します。表7-2の統計は、WebLogic Serverのパフォーマンスの概要を提供するものです。これらの統計の変化をリスニングするには、リスナーを作成して、属性が含まれるMBeanにリスナーを直接登録します。または、モニターMBeanを構成して、重要だと判断した統計のみを定期的にポーリングして報告させることもできます。(通知リスナーとフィルタの登録およびモニターとリスナーの登録を参照してください。)
表7-2 一般的にモニターされるWebLogic Serverランタイム統計
| 追跡する統計 | リスニングまたはモニターするMBean属性 |
|---|---|
サーバーの現在の状態 |
MBeanのタイプ: ServerLifeCycleRuntimeMBean 属性名: |
サーバーのリスニング・ポートのアクティビティ |
MBeanのタイプ: ServerRuntimeMBean 属性名: MBeanのタイプ: ServerMBean 属性名: この2つの属性を一緒に使用して、サーバーのリスニング・ポートにおける現在のアクティビティと、ポート上でバックログできるリクエストの総数を比較します。 |
メモリーとスレッドの使用状況 |
MBeanのタイプ: ThreadPoolRuntimeMBean 属性名: メモリー領域を占有しているがデータの処理には使用されていない、サーバーの実行キューのスレッド数を示します。 |
メモリーとスレッドの使用状況 |
MBeanのタイプ: ThreadPoolRuntimeMBean 属性名: サーバーの実行キューで待機するユーザー・リクエスト数を示します。 |
メモリーとスレッドの使用状況 |
MBeanのタイプ: JVMRuntimeMBean 属性名: サーバーのJVMヒープで現在使用可能なメモリー量(バイト単位)を示します。 |
データベース接続 |
MBeanのタイプ: JDBCDataSourceRuntimeMBean 属性名: JDBC接続プールでの現在アクティブな接続数を示します。 |
データベース接続 |
MBeanのタイプ: JDBCDataSourceRuntimeMBean 属性名: JDBC接続プールのアクティブな接続の最大数。この数は、接続プールがインスタンス化されるたびにゼロから開始します。 |
データベース接続 |
MBeanのタイプ: JDBCDataSourceRuntimeMBean 属性名: リークされた接続の総数を示します。リークされた接続はチェックアウト済みの接続ですが、 |
データベース接続 |
MBeanのタイプ: JDBCDataSourceRuntimeMBean 属性名: 接続プールに接続する平均時間を示します。 |
データベース接続 |
MBeanのタイプ: JDBCDataSourceRuntimeMBean 属性名: 接続プールがデータ・ストアへの再接続に失敗した場合を示します。アプリケーションでは、この属性がインクリメントしたり、しきい値に達したりすると、許容できる中断時間のレベルに応じてリスナーに通知できます。 |
MBeanが送信する通知を直接リスニングするには、次の手順に従います。
通知リスナーを作成するには、次の手順に従います。
例7-1 通知リスナー
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.AttributeChangeNotification;
public class MyListener implements NotificationListener {
public void handleNotification(Notification notification, Object obj) {
if(notification instanceof AttributeChangeNotification) {
AttributeChangeNotification attributeChange =
(AttributeChangeNotification) notification;
System.out.println("This notification is an
AttributeChangeNotification");
System.out.println("Observed Attribute: " +
attributeChange.getAttributeName() );
System.out.println("Old Value: " + attributeChange.getOldValue() );
System.out.println("New Value: " + attributeChange.getNewValue() );
}
}
}
例7-1は、AttributeChangeNotificationのメソッドを使用して、値が変化した属性の名前と古い値および新しい値を取得する簡単なリスナーです。
JMX 1.2では、リスニングするMBeanとは別のJVMで動作するリスナーのプログラミングに関する特別な要件はありません。
(javax.management.MBeanServerConnectionを使用して)リモートJMXエージェントへの接続を確立すると、JMXによってJVM間のデータの共有が処理されます。リモートJVMから接続を確立する手順については、「通知リスナーとフィルタの登録」,を参照してください。
NotificationListenerクラスを作成するときに、以下の推奨事項を考慮してください。
通知フィルタを使用しない限り、リスナーはそのリスナーが登録されているMBeanからの(すべての通知型の)すべての通知を受信します。
MBeanから送信されるすべての通知に1つのリスナーを使用するのではなく、フィルタとリスナーを組み合せて使用するのが最適です。複数のリスナーを使用するとJVMの初期化に時間がかかりますが、そのかわりにコードの保守が容易になります。
WebLogic Server環境にモニターする必要のあるMBeanタイプの複数のインスタンスがある場合は、1つの通知リスナーを作成して、モニターするMBeanインスタンスと同じ数だけ登録クラスを作成できます。
たとえば、WebLogic Serverドメインに3つのJDBCデータ・ソースがある場合は、AttributeChangeNotificationをリスニングする1つのリスナー・クラスを作成できます。次に、3つの登録クラスを作成します。各登録クラスは、リスナーをJDBCDataSourceRuntimeMBeanの特定のインスタンスに登録します。
handleNotificationメソッド・シグネチャにはhandbackオブジェクトの引数が含まれていますが、リスナーではhandbackオブジェクトからデータを取得したり、handbackオブジェクトを操作したりする必要はありません。それは、リスナーがMBeanエミッタに関する情報を関連付けるのを助ける不透明なオブジェクトです。
通知ブロードキャスタをブロックしないように、handleNotificationメソッドの実装はできるだけ早く復帰する必要があります。
特殊な通知型のメソッドを呼び出す場合は、そのメソッド呼出しをif文でラップして、リスナーがすべての型の通知オブジェクトのメソッドを呼び出さないようにします。
JDK 1.5では、指定する条件に一致した通知を転送するように構成できる、簡単なフィルタ・クラスが2つ用意されています。JDKのフィルタ・クラスを構成するには、次の手順に従います。
たとえば、以下のコード行では、Stateという属性で変更があった場合にのみ属性変更通知を転送するAttributeChangeNotificationFilterを構成します。
AttributeChangeNotificationFilter filter =
new AttributeChangeNotificationFilter();
filter.enableAttribute("State");
JDKのフィルタ・クラスでは単純過ぎて要件に合わない場合は、より高度なカスタム・フィルタ・クラスを作成できます。(Java SE 7 API仕様のNotificationFilter (http://docs.oracle.com/javase/7/docs/api/javax/management/NotificationFilter.html)を参照してください。)ただし、カスタム・フィルタを使用すると、リスナーおよびフィルタのパッケージ化とデプロイメントが複雑になるため、できる限りJDKのフィルタ・クラスを使用することをお薦めします。「WebLogic Serverにリスナーのパッケージ化およびデプロイ化」を参照してください
通知リスナー・クラスを実装したら、MBeanインスタンスにリスナーを登録する(また、必要に応じてフィルタを構成して登録する)追加のクラスを作成します。
通知リスナーとフィルタをMBeanに登録するには、次の手順に従います。
例7-2 ServerLifeCycleRuntimeMBeanへのリスナーの登録
import java.util.Hashtable;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.naming.Context;
import javax.management.AttributeChangeNotificationFilter;
public class RegisterListener {
private static MBeanServerConnection connection;
private static JMXConnector connector;
private static final ObjectName service;
// Initializing the object name for DomainRuntimeServiceMBean
// so it can be used throughout the class.
static {
try {
service = new ObjectName(
"com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanserv
ers.domainruntime.DomainRuntimeServiceMBean");
}catch (MalformedObjectNameException e) {
throw new AssertionError(e.getMessage());
}
}
/*
* Initialize connection to the Domain Runtime MBean Server
* each server in the domain hosts its own instance.
*/
public static void initConnection(String hostname, String portString,
String username, String password) throws IOException,
MalformedURLException {
String protocol = "t3";
Integer portInteger = Integer.valueOf(portString);
int port = portInteger.intValue();
String jndiroot = "/jndi/";
String mserver = "weblogic.management.mbeanservers.domainruntime";
JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname, port,
jndiroot + mserver);
Hashtable h = new Hashtable();
h.put(Context.SECURITY_PRINCIPAL, username);
h.put(Context.SECURITY_CREDENTIALS, password);
h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
"weblogic.management.remote");
connector = JMXConnectorFactory.connect(serviceURL, h);
connection = connector.getMBeanServerConnection();
}
/*
* Get an array of ServerLifeCycleRuntimeMBeans
*/
public static ObjectName[] getServerLCRuntimes() throws Exception {
ObjectName domainRT = (ObjectName) connection.getAttribute(service,
"DomainRuntime");
return (ObjectName[]) connection.getAttribute(domainRT,
"ServerLifecycleRuntimes");
}
public static void main(String[] args) throws Exception {
String hostname = args[0];
String portString = args[1];
String username = args[2];
String password = args[3];
try {
//Instantiating your listener class.
MyListener listener = new MyListener();
AttributeChangeNotificationFilter filter =
new AttributeChangeNotificationFilter();
filter.enableAttribute("State");
initConnection(hostname, portString, username, password);
//Passing the name of the MBeans and your listener class to the
//addNotificationListener method of MBeanServer.
ObjectName[] serverLCRT = getServerLCRuntimes();
int length= (int) serverLCRT.length;
for (int i=0; i < length; i++) {
connection.addNotificationListener(serverLCRT[i], listener,
filter, null);
System.out.println("\n[myListener]: Listener registered with"
+serverLCRT[i]);
}
//Keeping the remote client active.
System.out.println("pausing...........");
System.in.read();
} catch(Exception e) {
System.out.println("Exception: " + e);
}
}
}
サンプル・クラスでは、例7-1のリスナーとJDKのAttributeChangeNotificationFilterを、ドメインのServerLifeCycleRuntimeMBeanに登録します。このクラスではhandbackオブジェクトは渡しません。
このサンプルで、weblogicはMBean属性を表示および変更する許可を与えられたユーザーです。MBeanの表示や変更を行う許可については、Oracle WebLogic Serverロールおよびポリシーによるリソースの保護のユーザー、グループおよびセキュリティ・ロールを参照してください。
サンプル・クラスには、RegisterListenerクラスをアクティブに保ち、メイン・プログラムを終了しないコードも含まれています。リスナー・クラスは、クラスの呼出しとアクティブの維持を行う、より大きなアプリケーションのコンテキストで動作するため、このコードは通常は必要ありません。ここでは、簡単にコンパイルしてサンプルの機能を確認できるように含まれています。
JMXリスナーは、リモート・アプリケーションとして、WebLogic Server起動クラスとして(サーバーが起動するとすぐにリスナーが使用可能になります)、またはWebLogic Serverにデプロイする他のアプリケーションの内部に、パッケージ化してデプロイできます。
JDKのフィルタを使用する場合は、フィルタ・クラスをパッケージ化する必要はありません。常にJDKから使用できるようになっています。
表7-3では、リスナーとカスタム・フィルタをパッケージ化してデプロイする方法について説明します。
表7-3 リスナーとカスタム・フィルタのパッケージ化とデプロイ
| リスナーのデプロイ方法 | リスナーに関する手順 | カスタム・フィルタに関する手順 |
|---|---|---|
リモート・アプリケーションとして |
リスナーのクラスをリモート・クライアントのクラスパスで使用可能にします。 |
フィルタのクラスをリモート・クライアントのクラスパスで使用可能にします。 また、モニターするMBeanをホストしている各サーバー・インスタンスのクラスパスにフィルタ・クラスを追加します。それには、クラスをJARファイルにアーカイブして、そのJARを各サーバーの |
WebLogic Server起動クラスとして |
リスナー・クラスをサーバーのクラスパスに追加します。それには、クラスをJARファイルにアーカイブして、そのJARをサーバーの |
フィルタ・クラスをサーバーのクラスパスに追加します。それには、クラスをJARファイルにアーカイブして、そのJARをサーバーの |
WebLogic Serverにデプロイするアプリケーションの一部として |
リスナー・クラスをアプリケーションと一緒にパッケージ化します。 |
リスナー・クラスをアプリケーションと一緒にパッケージ化します。 また、モニターするMBeanをホストしている各サーバー・インスタンスのクラスパスにフィルタ・クラスを追加します。それには、次のいずれかを行います。
|
サーバーやJDBCデータ・ソースなどのWebLogic Serverリソースを作成すると、WebLogic Serverは構成MBeanを作成してドメイン・ランタイムMBeanサーバーに登録します。
これらのイベントをリスニングするには、リスナーをjavax.management.MBeanServerDelegateに登録します。
MBeanが登録または登録解除されるたびに、javax.management.MBeanServerNotification型の通知を送信します。Java SE 7 API仕様のMBeanServerDelegate (http://docs.oracle.com/javase/7/docs/api/javax/management/MBeanServerDelegateMBean.html)を参照してください。
例7-3のサンプル・リスナーに関する以下の点に注意してください。
登録されたWebLogic Server MBeanのタイプに関する情報を提供するために、リスナーは登録されたMBeanのオブジェクト名を検索します。すべてのWebLogic Server MBeanオブジェクト名には、名前が「Type」で、値がMBeanのタイプを表す、キー・プロパティが含まれています。たとえば、ServerRuntimeMBeanのインスタンスには、オブジェクト名にType=ServerRuntimeキー・プロパティが含まれています。
すべてのJMX通知にはType属性が含まれており、その値によって通知の分類とフィルタ処理ができます。MBeanServerNotificationのType属性には、2つの文字列「JMX.mbean.registered」または「JMX.mbean.unregistered」のうち1つだけ含まれています。また、JMX通知にはType属性の値を返すgetTypeメソッドも含まれます。
例7-3のリスナーは、Type属性の値に応じて異なるコード行を呼び出します。
JDBCDataSourceRuntimeMBeanが登録されると、リスナーはこのMBeanのオブジェクト名をカスタム・メソッドに渡します。カスタム・メソッドはリスナーを登録し、JDBCDataSourceRuntimeMBean用のフィルタを構成します。このMBeanリスナーは、MBeanのEnabled属性が変更されるとメッセージを送信します。
カスタム・メソッドの実装クラスは(フィルタ・クラスではなく) 登録クラス内にあるので、メソッドは登録クラスのMBeanサーバーへの接続を再利用できます。再利用によってリソースが有効に活用され、複数のクラスに資格証明とURLを格納する必要がなくなります。
例7-3 例: MBeanの登録および登録解除のリスニング
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.MBeanServerNotification;
import javax.management.ObjectName;
public class DelegateListener implements NotificationListener {
public void handleNotification(Notification notification, Object obj) {
if (notification instanceof MBeanServerNotification) {
MBeanServerNotification msnotification =
(MBeanServerNotification) notification;
// Get the value of the MBeanServerNotification
// Type attribute, which contains either
// "JMX.mbean.registered" or "JMX.mbean.unregistered"
String nType = msnotification.getType();
// Get the object name of the MBean that was registered or
// unregistered
ObjectName mbn = msnotification.getMBeanName();
// Object names for WebLogic Server MBeans always contain
// a "Type" key property, which indicates the
// MBean's type (such as ServerRuntime or Log)
String key = mbn.getKeyProperty("Type");
if (nType.equals("JMX.mbean.registered")) {
System.out.println("A " + key + " has been created.");
System.out.println("Full MBean name: " + mbn);
System.out.println("Time: " + msnotification.getTimeStamp());
if (key.equals("JDBCDataSourceRuntime")) {
// Registers a listener with a ServerRuntimeMBean.
// By defining the "registerwithServerRuntime" method
// in the "ListenToDelegate" class, you can reuse the
// connection that "ListenToDelegate" established;
// in addition to being an efficient way to use resources,
// it eliminates the need to store credentials and URLs in
// multiple classes.
ListenToDelegate.registerwithJDBCDataSourceRuntime(mbn);
}
}
if (nType.equals("JMX.mbean.unregistered")) {
System.out.println("An MBean has been unregistered");
System.out.println("Server name: " +
mbn.getKeyProperty("Name"));
System.out.println("Time: " + msnotification.getTimeStamp());
System.out.println("Full MBean name: "
+ msnotification.getMBeanName());
}
}
}
}
例7-4では、登録クラスのメソッドを示します。以下の点に注意してください。
MBeanServerDelegateのJMXオブジェクト名は常に"JMImplementation:type=MBeanServerDelegate"。
mainメソッドでは、通知のType属性の値が「JMX.mbean.registered」または「JMX.mbean.unregistered」で始まる場合にのみ通知を転送するように、javax.management.NotificationFilterSupportのインスタンスを構成します。
registerwithJDBCDataSourceRuntimeメソッドは、指定されたJDBCDataSourceRuntimeMBeanインスタンスに例7-1のリスナーを登録します。このメソッドではjavax.management.AttributeChangeNotificationFilterも構成します。これは、Enabledという属性の変更について説明するAttributeChangeNotificationのみを転送します。
これらのメソッドをコンパイルして実行するには、例7-2の補助的なカスタム・メソッドを使用し、生成されたクラスをリモートJMXクライアントとして実行します。
例7-4 例: MBeanServerDelegateへのリスナーの登録
public static void main(String[] args) throws Exception {
String hostname = args[0];
String portString = args[1];
String username = args[2];
String password = args[3];
ObjectName delegate = new ObjectName(
"JMImplementation:type=MBeanServerDelegate");
try {
//Instantiating your listener class.
StartStopListener slistener = new StartStopListener();
NotificationFilterSupport filter = new NotificationFilterSupport();
filter.enableType("JMX.mbean.registered");
filter.enableType("JMX.mbean.unregistered");
/* Invoke a custom method that establishes a connection to the
* Domain Runtime MBean Server and uses an instance of
* MBeanServerConnection to represents the connection. The custom
* method assigns the MBeanServerConnection to a class-wide, static
* variable named "connection".
*/
initConnection(hostname, portString, username, password);
//Passing the name of the MBeans and your listener class to the
//addNotificationListener method of MBeanServer.
connection.addNotificationListener(delegate, slistener, filter,
null);
System.out.println("\n[myListener]: Listener registered ...");
//Keeping the remote client active.
System.out.println("pausing...........");
System.in.read();
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
// Called by the listener if it receives notification of a
// JDBCDataSourceRuntimeMBean being registered.
public static void registerwithJDBCDataSourceRuntime(ObjectName mbname) {
try {
MyListener mylistener = new MyListener();
AttributeChangeNotificationFilter filter =
new AttributeChangeNotificationFilter();
filter.enableAttribute("Enabled");
connection.addNotificationListener(mbname, mylistener,
filter, null);
} catch (Exception e) {
System.out.println("Exception: " + e);
}
}
モニターMBeanを構成して使用するには、次の手順に従います。
JMXでは、特定のタイプの変更を観察する特別なモニターMBeanを提供しています。
StringMonitorMBean - 値がStringの属性を観察します。
このモニターを使用して、ServerLifeCycleRuntimeMBean Stateなどの属性を定期的に観察します。
StringMonitorMBeanを実装するJava SE 7 API仕様のjavax.management.monitor.StringMonitor (http://docs.oracle.com/javase/7/docs/api/javax/management/monitor/StringMonitor.html)を参照してください。
GaugeMonitorMBean - 値がNumberの属性を観察します。
このモニターを使用して、通常の処理の結果として値が変動する属性を観察します。属性の値が特定の範囲外まで変動した場合に通知を送信するように、ゲージ・モニターを構成します。たとえば、ゲージ・モニターを使用してThreadPoolRuntimeMBean StandbyThreadCount属性をモニターし、サーバーの未使用かつ使用可能なスレッドの数が許容範囲内にあることを確認できます。
GaugeMonitorMBeanを実装するJava SE 7 API仕様のjavax.management.monitor.GaugeMonitor (http://docs.oracle.com/javase/7/docs/api/javax/management/monitor/GaugeMonitor.html)を参照してください。
CounterMonitorMBean - 値がNumberの属性を観察します。
このモニターを使用して、通常の処理の結果として値が増加する属性を観察します。属性の値が上限しきい値を超えた場合に通知を送信するように、カウンタ・モニターを構成します。しきい値を増やして指定された時点でしきい値をリセットするように、カウンタ・モニターを構成することもできます。
たとえば、サーバーでのヒット総数を追跡して、100ヒット増えるたびに通知を受けるようにするには、ServerRuntimeMBean SocketsOpenedTotalCount属性を観察するカウンタ・モニターを使用します。
CounterMonitorMBeanを実装するJava SE 7 API仕様のjavax.management.monitor.CounterMonitor (http://docs.oracle.com/javase/7/docs/api/javax/management/monitor/CounterMonitor.html)を参照してください。
すべてのモニターMBeanはjavax.management.monitor.MonitorNotification型の通知を送信します。モニターMBeanは通知を生成するときに、特定の値を通知のTypeプロパティに書き込んで、通知を生成したイベントについて記述します。表7-4では、様々なタイプのモニターMBeanがエンコードするTypeプロパティの値について説明します。フィルタまたはリスナーは通知のgetType()メソッドを使用して、Typeプロパティ内のStringを取得します。
表7-4 モニターMBeanとMonitorNotificationのTypeプロパティ
| モニターMBeanのタイプ | MonitorNotificationのTypeプロパティ内にエンコードされる文字列 |
|---|---|
CounterMonitor |
|
GaugeMonitor |
|
StringMonitor |
|
エラーが発生した場合、すべてのモニターは通知のTypeプロパティに以下のいずれかの値をエンコードします。
jmx.monitor.error.mbean - 観察対象MBeanがMBeanサーバーに登録されていないことを示します。通知では、観察対象のオブジェクト名が示されます。
jmx.monitor.error.attribute - 観察対象の属性が観察対象オブジェクトに存在しないことを示します。通知では、観察対象のオブジェクト名と属性名が示されます。
jmx.monitor.error.type - 観察対象の属性値のオブジェクト・インスタンスがnullか、またはモニターに対応していない型であることを示します。通知では、観察対象のオブジェクト名と属性名が示されます。
jmx.monitor.error.runtime - 観察対象の属性値の取得中に(上記以外の理由で)スローされた例外が含まれます。
また、カウンタ・モニターとゲージ・モニターは、以下のような場合にTypeプロパティにjmx.monitor.error.thresholdをエンコードできます。
カウンタ・モニターの場合、しきい値、オフセット、または係数の型が観察対象のカウンタ属性と同じでない場合
ゲージ・モニターの場合、下限しきい値または上限しきい値が観察対象のゲージ属性と同じでない場合
観察対象の属性が指定した条件に一致する場合、モニターMBeanは通知を送信します。MonitorNotification用のリスナーを作成するための特別な要件はありません。手順は、次の点を除いて通知リスナーの作成で説明した手順と同じです。
MonitorNotification型の通知をリスニングします。
必要に応じて、javax.management.monitor.MonitorNotificationクラスをインポートし、そのメソッドを呼び出して、通知を生成したイベントに関する追加情報を取得できます。
例7-5を参照してください。
例7-5 モニター通知用のリスナー
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.monitor.MonitorNotification;
public class MonitorListener implements NotificationListener {
public void handleNotification(Notification notification, Object obj) {
if(notification instanceof Notification) {
Notification notif = (Notification) notification;
System.out.println("Notification type" + notif.getType() );
System.out.println("Message: " + notif.getMessage() );
}
if (notification instanceof MonitorNotification) {
MonitorNotification mn = (MonitorNotification) notification;
System.out.println("Observed Attribute: " +
mn.getObservedAttribute());
System.out.println("Trigger: " + mn.getTrigger() );
}
}
}
モニターMBeanを使用するには、まず、MBeanサーバー内でモニターMBeanのインスタンスを作成して登録する必要があります。次に、作成したモニターMBeanにリスナーを登録します。この手順のすべてを1つのクラスの中で行うことができます。
モニターMBeanを登録し、リスナーを登録して、モニターMBeanを起動するには、次の手順に従います。
例7-6では、CounterMonitorMBeanを作成および構成して、ドメインの各ServerRuntimeMBeanインスタンスのSocketsOpenedTotalCount属性を観察するクラスのmain()メソッドを示します。(Oracle WebLogic Server MBeanリファレンスのSocketsOpenedTotalCountを参照してください。)
このサンプル・コードでは、ServerRuntimeMBeanの複数のインスタンスをモニターできるように、ドメイン・ランタイムMBeanサーバーに接続します。以下の点に注意してください。
CounterMonitorMBeanの1つのインスタンスでServerRuntimeMBeanのすべてのインスタンスをモニターします。ドメイン・ランタイムMBeanサーバーは、別のJVMで動作するServerRuntimeMBeanインスタンスへの結合アクセスをCounterMonitorMBeanに与えています。
リスナー・クラスのとフィルタ・クラスの1つのインスタンスが、CounterMonitorMBeanからの通知をリスニングしてフィルタ処理します。
このmainメソッドをコンパイルして実行するには、例7-2の補助的なカスタム・メソッドを使用し、生成されたクラスをリモートJMXクライアントとして実行します。
例7-6 例: CounterMonitorMBeanとそのリスナーの登録
public static void main(String[] args) throws Exception {
String hostname = args[0];
String portString = args[1];
String username = args[2];
String password = args[3];
try {
/* Invokes a custom method that establishes a connection to the
* Domain Runtime MBean Server and uses an instance of
* MBeanServerConnection to represents the connection. The custom
* method assigns the MBeanServerConnection to a class-wide, static
* variable named "connection".
*/
initConnection(hostname, portString, username, password);
//Creates and registers the monitor MBean.
ObjectName monitorON =
new ObjectName("mycompany:Name=mySocketMonitor,Type=CounterMonitor");
String classname = "javax.management.monitor.CounterMonitor";
System.out.println("===> create mbean "+monitorON);
connection.createMBean(classname, monitorON);
//Configure the monitor MBean.
Number initThreshold = new Long(2);
Number offset = new Long(1);
connection.setAttribute(monitorON,
new Attribute("InitThreshold", initThreshold));
connection.setAttribute(monitorON, new Attribute("Offset", offset));
connection.setAttribute(monitorON,
new Attribute("Notify", new Boolean(true)));
//Gets the object names of the MBeans that you want to monitor.
ObjectName[] serverRT = getServerRuntimes();
int length= (int) serverRT.length;
for (int i=0; i < length; i++) {
//Sets each instance of ServerRuntime MBean as a monitored MBean.
System.out.println("===> add observed mbean "+serverRT[i]);
connection.invoke(monitorON, "addObservedObject",
new Object[] { serverRT[i] },
new String[] { "javax.management.ObjectName" });
Attribute attr = new Attribute("ObservedAttribute",
"SocketsOpenedTotalCount");
connection.setAttribute(monitorON, attr);
}
// Instantiates your listener class and configures a filter to
// forward only counter monitor messages.
MonitorListener listener = new MonitorListener();
NotificationFilterSupport filter = new NotificationFilterSupport();
filter.enableType("jmx.monitor.counter");
filter.enableType("jmx.monitor.error");
//Uses the MBean server's addNotificationListener method to
//register the listener and filter with the monitor MBean.
System.out.println("===> ADD NOTIFICATION LISTENER TO "+monitorON);
connection.addNotificationListener(monitorON, listener, filter, null);
System.out.println("\n[myListener]: Listener registered ...");
//Starts the monitor.
connection.invoke(monitorON, "start", new Object[] { }, new String[] { });
//Keeps the remote client active.
System.out.println("pausing...........");
System.in.read();
} catch(Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
}
}