3.11. 服务器生命周期事件通知

您可以使用 JBoss EAP core-management 子系统Jakarta Management 为服务器生命周期事件设置通知。服务器运行时配置状态或服务器运行状态的变化将触发通知。

JBoss EAP 的服务器运行时配置状态为 STARTING、RUN NINGRELOAD_REQUIRED、REART_REQUIREDSTOPPINGSTOPPED

JBoss EAP 的服务器运行状态为 STARTING、NORMA L ADMIN_ONLYPRE_SUSPEND ING、SUSPENDINGSUSPENDEDSTOPPINGSTOPPED

3.11.1. 使用核心管理系统监控服务器生命周期事件

您可以将侦听器注册到 JBoss EAP 核心管理 子系统,以监控服务器生命周期事件。下列步骤演示了如何创建和注册将事件记录到文件中的示例侦听器。

  1. 创建监听器。

    创建 org.wildfly.extension.core.management.client.ProcessStateListener 实施,如下例所示。

    示例: Listener Class

    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 中正确加载、初始化和删除多次。
    • 通知监听器正在阻止,允许响应服务器状态变化。实施必须确保它们不会阻断或死锁。
    • 每个侦听器实例在自己的线程中执行,而且顺序不受保证。
  2. 编译该类,并将它打包为 JAR。

    请注意,要编译,您需要依赖于 org.wildfly.core:wildfly-core-management-client Maven 模块。

  3. 添加 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
    重要

    使用 模块 管理 CLI 命令添加和删除模块,仅作为技术预览提供。此命令不适合在受管域中使用,或在远程连接管理 CLI 时使用。在生产环境中,应当手动 添加 和删除 模块。

    技术预览功能不包括在红帽生产服务级别协议(SLA)中,且其功能可能并不完善。因此,红帽不建议在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。

    如需有关 技术预览功能支持范围 的信息,请参阅红帽客户门户网站中的技术预览功能支持范围。

  4. 注册侦听器。

    使用下列管理 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})

现在,服务器生命周期事件会根据上面的 SimpleList ener 类记录到 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

这表明运行状态已从 正常 更改为 暂停,然后从 暂停 变为 暂停

3.11.2. 使用 Jakarta 管理通知监控服务器生命周期事件

您可以注册 Jakarta 管理通知监听程序来监控服务器生命周期事件。以下步骤演示了如何创建和添加将事件记录到文件中的示例侦听器。

  1. 创建监听器。

    创建 javax.management.NotificationListener 实施,如下例所示:

    示例: Listener Class

    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);
        }
      }
    }

  2. 注册通知监听程序。

    将通知监听程序添加到 MBeanServer

    示例:添加通知列表

    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    server.addNotificationListener(ObjectName.getInstance("jboss.root:type=state"), new StateNotificationListener(), null, null);

  3. 打包并部署到 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'

这表明运行状态已从 正常 更改为 暂停,然后从 暂停 变为 暂停