3.11. サーバーライフサイクルイベントの通知
JBoss EAP core-management
サブシステム または JMX を使用してサーバーライフサイクルイベントの通知を設定できます。サーバーランタイム設定の状態やサーバー稼働の状態が変更されると、通知が発生します。
JBoss EAP のサーバーランタイム設定の状態には、STARTING
、 RUNNING
、RELOAD_REQUIRED
、 RESTART_REQUIRED
、STOPPING
、および STOPPED
があります。
JBoss EAP のサーバー稼働の状態には、STARTING
、NORMAL
、ADMIN_ONLY
、PRE_SUSPEND
、SUSPENDING
、SUSPENDED
、STOPPING
、および STOPPED
があります。
3.11.1. core-management サブシステムを使用したサーバーライフサイクルイベントの監視
リスナーを JBoss EAP core-management
サブシステムに登録すると、サーバーのライフサイクルイベントを監視できます。以下の手順は、イベントをログファイルの記録するサンプルリスナーを作成および登録する方法を示しています。
リスナーを作成します。
以下の例のように、
org.wildfly.extension.core.management.client.ProcessStateListener
の実装を作成します。例: リスナークラス
package org.simple.lifecycle.events.listener; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.wildfly.extension.core.management.client.ProcessStateListener; import org.wildfly.extension.core.management.client.ProcessStateListenerInitParameters; import org.wildfly.extension.core.management.client.RunningStateChangeEvent; import org.wildfly.extension.core.management.client.RuntimeConfigurationStateChangeEvent; public class SimpleListener implements ProcessStateListener { private File file; private FileWriter fileWriter; private ProcessStateListenerInitParameters parameters; public void init(ProcessStateListenerInitParameters parameters) { this.parameters = parameters; this.file = new File(parameters.getInitProperties().get("file")); try { fileWriter = new FileWriter(file, true); } catch (IOException e) { e.printStackTrace(); } } public void cleanup() { try { fileWriter.close(); } catch (IOException e) { e.printStackTrace(); } finally { fileWriter = null; } } public void runtimeConfigurationStateChanged(RuntimeConfigurationStateChangeEvent evt) { try { fileWriter.write(String.format("Runtime configuration state change for %s: %s to %s\n", parameters.getProcessType(), evt.getOldState(), evt.getNewState())); fileWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } public void runningStateChanged(RunningStateChangeEvent evt) { try { fileWriter.write(String.format("Running state change for %s: %s to %s\n", parameters.getProcessType(), evt.getOldState(), evt.getNewState())); fileWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } }
注記リスナーの実装時には以下に気をつけてください。
- サーバーがリロードすると、サーバーの停止時にリスナーはリッスンを停止し、サーバーの起動時にリスナーはリロードされます。そのため、実装では同じ JVM 内部でリスナーを適切に複数回ロード、初期化、および削除できるようにする必要があります。
- サーバー状態の変更に対応できるようにするため、リスナーへの通知はブロッキング状態になります。実装では、リスナーがブロックまたはデッドロックしないようにする必要があります。
- 各リスナーインスタンスは独自のスレッドで実行され、順番は保証されません。
クラスおよびパッケージを JAR にコンパイルします。
コンパイルするには、
org.wildfly.core:wildfly-core-management-client
Maven モジュールに依存する必要があります。JAR を JBoss EAP モジュールとして追加します。
以下の管理 CLI コマンドを使用し、モジュール名と JAR へのパスを提供します。
module add --name=org.simple.lifecycle.events.listener --dependencies=org.wildfly.extension.core-management-client --resources=/path/to/simple-listener-0.0.1-SNAPSHOT.jar
重要module
管理 CLI コマンドを使用したモジュールの追加および削除は、テクノロジープレビューとしてのみ提供されます。このコマンドは、管理対象ドメインでの使用や、リモートによる管理 CLI への接続時には適していません。本番環境ではモジュールを手作業で 追加 および 削除 してください。テクノロジープレビューの機能は、Red Hat の本番環境のサービスレベルアグリーメント (SLA) ではサポートされず、機能的に完全ではないことがあるため、Red Hat は本番環境での使用は推奨しません。テクノロジープレビューの機能は、最新の製品機能をいち早く提供して、開発段階で機能のテストを行いフィードバックを提供していただくことを目的としています。
テクノロジープレビュー機能のサポート範囲については、Red Hat カスタマーポータルの テクノロジープレビュー機能のサポート範囲 を参照してください。
リスナーを登録します。
以下のかんり CLI コマンドを使用してリスナーを
core-management
サブシステムに追加します。クラス、モジュール、およびサーバーライフサイクルイベントを記録するログファイルの場所を指定します。/subsystem=core-management/process-state-listener=my-simple-listener:add(class=org.simple.lifecycle.events.listener.SimpleListener, module=org.simple.lifecycle.events.listener,properties={file=/path/to/my-listener-output.txt})
上記の SimpleListener
クラスを基にしてサーバーライフサイクルのイベントが my-listener-output.txt
ファイルに記録されるようになりました。たとえば、管理 CLI で :suspend
コマンドを実行すると、以下が my-listener-output.txt
ファイルに出力されます。
Running state change for STANDALONE_SERVER: normal to suspending Running state change for STANDALONE_SERVER: suspending to suspended
これを見ると、稼働状態が normal
から suspending
に変わった後、suspending
から suspended
に変わったことがわかります。
3.11.2. JMX 通知を使用したサーバーライフサイクルイベントの監視
JMX 通知リスナーを登録すると、サーバーのライフサイクルイベントを監視できます。以下の手順は、イベントをログファイルの記録するサンプルリスナーを作成および追加する方法を示しています。
リスナーを作成します。
以下の例のように、
javax.management.NotificationListener
の実装を作成します。例: リスナークラス
import java.io.BufferedWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import javax.management.AttributeChangeNotification; import javax.management.Notification; import javax.management.NotificationListener; import org.jboss.logging.Logger; public class StateNotificationListener implements NotificationListener { public static final String RUNTIME_CONFIGURATION_FILENAME = "runtime-configuration-notifications.txt"; public static final String RUNNING_FILENAME = "running-notifications.txt"; private final Path targetFile; public StateNotificationListener() { this.targetFile = Paths.get("notifications/data").toAbsolutePath(); init(targetFile); } protected Path getRuntimeConfigurationTargetFile() { return this.targetFile.resolve(RUNTIME_CONFIGURATION_FILENAME); } protected Path getRunningConfigurationTargetFile() { return this.targetFile.resolve(RUNNING_FILENAME); } protected final void init(Path targetFile) { try { Files.createDirectories(targetFile); if (!Files.exists(targetFile.resolve(RUNTIME_CONFIGURATION_FILENAME))) { Files.createFile(targetFile.resolve(RUNTIME_CONFIGURATION_FILENAME)); } if (!Files.exists(targetFile.resolve(RUNNING_FILENAME))) { Files.createFile(targetFile.resolve(RUNNING_FILENAME)); } } catch (IOException ex) { Logger.getLogger(StateNotificationListener.class).error("Problem handling JMX Notification", ex); } } @Override public void handleNotification(Notification notification, Object handback) { AttributeChangeNotification attributeChangeNotification = (AttributeChangeNotification) notification; if ("RuntimeConfigurationState".equals(attributeChangeNotification.getAttributeName())) { writeNotification(attributeChangeNotification, getRuntimeConfigurationTargetFile()); } else { writeNotification(attributeChangeNotification, getRunningConfigurationTargetFile()); } } private void writeNotification(AttributeChangeNotification notification, Path path) { try (BufferedWriter in = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.APPEND)) { in.write(String.format("%s %s %s %s", notification.getType(), notification.getSequenceNumber(), notification.getSource().toString(), notification.getMessage())); in.newLine(); in.flush(); } catch (IOException ex) { Logger.getLogger(StateNotificationListener.class).error("Problem handling JMX Notification", ex); } } }
通知リスナーを登録します。
通知リスナーを
MBeanServer
に追加します。例: 通知リスナーの追加
MBeanServer server = ManagementFactory.getPlatformMBeanServer(); server.addNotificationListener(ObjectName.getInstance("jboss.root:type=state"), new StateNotificationListener(), null, null);
- JBoss EAP にパッケージ化およびデプロイします。
上記の StateNotificationListener
クラスを基にしてサーバーライフサイクルイベントがファイルに記録されるようになりました。たとえば、管理 CLI で :suspend
コマンドを実行すると、以下が running-notifications.txt
ファイルに出力されます。
jmx.attribute.change 5 jboss.root:type=state The attribute 'RunningState' has changed from 'normal' to 'suspending' jmx.attribute.change 6 jboss.root:type=state The attribute 'RunningState' has changed from 'suspending' to 'suspended'
これを見ると、稼働状態が normal
から suspending
に変わった後、suspending
から suspended
に変わったことがわかります。