第 10 章:JMX Configurator

顾名思义,JMXConfigurator允许通过 JMX 配置回发。简而言之,它使您可以从默认配置文件,指定文件或 URL 重新配置logback,列出 Logger 并修改 Logger 级别。

使用 JMX 配置器

如果您的服务器在 JDK 1.6 或更高版本上运行,则只需在命令行上调用jconsole应用程序,然后连接到服务器的 MBeanServer。如果运行的是较早的 JVM,则应阅读JMX 启用服务器上的内容。

JMXConfigurator由您的logback配置文件中的一行启用,如下所示:

<configuration>
  <jmxConfigurator />
  
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%date [%thread] %-5level %logger{25} - %msg%n</Pattern>
    </layout>
  </appender>

  <root level="debug">
    <appender-ref ref="console" />
  </root>  
</configuration>

使用* jconsole *连接到服务器后,在 MBeans 面板上的“ ch.qos.logback.classic.jmx.Configurator”文件夹下,您应该看到几个操作可供选择,如下图所示:

在 jconsole 中查看的 JMXConfigurator 屏幕截图

jmxConfigurator

因此,您可以

  • 使用默认配置文件重新加载回发配置。

  • 使用指定的 URL 重新加载配置。

  • 用指定的文件重新加载配置。

  • 设置指定 Logger 的级别。要设置为 null,请将字符串“ null”作为值传递。

  • 获取指定 Logger 的级别。返回的值可以为 null。

  • 获取指定 Logger 的effective level

JMXConfigurator将现有 Logger 的列表和状态列表作为属性公开。

状态列表可以帮助您诊断回发的内部状态。

statusList.gif

避免内存泄漏

如果您的应用程序部署在 Web 服务器或应用程序服务器中,则JMXConfigurator实例的注册会创建一个从系统类加载器到您应用程序的引用,这将防止在停止或重新部署该应用程序时对其进行垃圾回收,从而导致在严重的内存泄漏中。

因此,除非您的应用程序是独立的 Java 应用程序,否则您必须从 JVM 的 Mbeans 服务器中注销JMXConfigurator实例。调用适当的LoggerContextreset()方法将自动注销任何 JMXConfigurator 实例。重置 logger 上下文的一个好地方是javax.servlet.ServletContextListenercontextDestroyed()方法。这是示例代码:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;

public class MyContextListener implements ServletContextListener {

  public void contextDestroyed(ServletContextEvent sce) {
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
    lc.stop();
  }

  public void contextInitialized(ServletContextEvent sce) {
  }
}

具有多个 Web 应用程序的 JMXConfigurator

如果您在同一服务器上部署多个 Web 应用程序,并且尚未覆盖默认的context selector,并且在* WEB-下将* logback-*。jar slf4j-api.jar 的副本放置在每个 Web 应用程序的 INF/lib *文件夹,然后默认情况下,每个JMXConfigurator实例将以相同的名称注册,即“ ch.qos.logback.classic:Name = default,Type = ch.qos.logback.classic .jmx.JMXConfigurator”。换句话说,默认情况下,与每个 Web 应用程序中的 logger 上下文相关联的各种JMXConfigurator实例将发生冲突。

为避免此类意外冲突,您只需设置应用程序的日志上下文的名称JMXConfigurator就会自动使用您设置的名称。

例如,如果您部署两个名为“ Koala”和“ Wombat”的 Web 应用程序,那么您将使用 Koala 的 logback 配置进行编写

<configuration>
  <contextName>Koala</contextName>
  <jmxConfigurator/>
  ...
<configuration>

在 Wombat logback 配置文件中,您将编写:

<configuration>
  <contextName>Wombat</contextName>x
  <jmxConfigurator/>
  ...
<configuration>

在 jconsole 的 MBeans 面板中,您将看到两个不同的JMXConfigurator实例:

multiple.gif

您可以借助<jmxConfigurator>元素的“ objectName”属性完全控制在 MBeans 服务器上注册 JMXConfigurator 的名称。

JMX 启用您的服务器

如果您的服务器运行 JDK 1.6 或更高版本,则默认情况下应启用 JMX。

对于较早的 JVM,建议您参考 Web 服务器的 JMX 相关文档。此类文档适用于TomcatJetty。在本文档中,我们简要描述了 Tomcat 和 Jetty 所需的配置步骤。

在 Jetty 中启用 JMX(已在 JDK 1.5 和 JDK 1.6 下测试)

以下已在 JDK 1.5 和 1.6 下进行了测试。在 JDK 1.6 和更高版本中,服务器默认情况下启用 JMX,您可以但不必遵循以下步骤。在 JDK 1.5 下,要在 Jetty 中添加 JMX 支持,需要在* $ JETTY_HOME/etc/jetty.xml *配置文件中添加许多内容。以下是需要添加的元素:

<Call id="MBeanServer" class="java.lang.management.ManagementFactory" 
      name="getPlatformMBeanServer"/>

<Get id="Container" name="container">
  <Call name="addEventListener">
    <Arg>
      <New class="org.mortbay.management.MBeanContainer">
        <Arg><Ref id="MBeanServer"/></Arg>
        <Call name="start" />
      </New>
    </Arg>
  </Call>
</Get>

如果希望通过jconsole应用程序访问 Jetty 公开的 MBean,则需要在设置 Java 系统属性“ com.sun.management.jmxremote”之后启动 Jetty。

对于 Jetty 的独立版本,它转换为:

java -Dcom.sun.management.jmxremote -jar start.jar [配置文件]

并且,如果您希望将 Jetty 作为 Maven 插件启动,则需要通过MAVEN_OPTS shell 变量设置“ com.sun.management.jmxremote”系统属性:

MAVEN_OPTS =“-Dcom.sun.management.jmxremote ” mvn jetty:run

然后,您可以通过jconsole访问 Jetty 以及logback的JMXConfigurator所访问的 MBean。

jconsole15_jetty.gif

构建连接后,您应该可以访问JMXXConfigurator,如上面的screenshot所示。

带有 Jetty 的 MX4J(已在 JDK 1.5 和 1.6 下测试)

如果您希望通过 MX4J 的 HTTP 接口访问JMXConfigurator并假设您已经下载MX4J,则需要通过添加设置 Management 端口的指令来修改前面讨论的 Jetty 配置文件。

<Call id="MBeanServer"
    class="java.lang.management.ManagementFactory"
    name="getPlatformMBeanServer"/>

<Get id="Container" name="container">
  <Call name="addEventListener">
    <Arg>
      <New class="org.mortbay.management.MBeanContainer">
        <Arg><Ref id="MBeanServer"/></Arg>
        <Set name="managementPort">8082</Set>
        <Call name="start" />
      </New>
    </Arg>
  </Call>
</Get>

此外,需要将* mx4j-tools.jar *添加到 Jetty 的 Classpath 中。

如果您将 Jetty 作为 Maven 插件运行,则需要添加* mx4j-tools *作为依赖项。

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>maven-jetty-plugin</artifactId>
  <configuration>
    <jettyConfig>path/to/jetty.xml</jettyConfig>
    ...
  </configuration>
  <dependencies>
    <dependency>
      <groupId>mx4j</groupId>
      <artifactId>mx4j-tools</artifactId>
      <version>3.0.1</version>
    </dependency>
  </dependencies>
</plugin>

使用以上配置启动 Jetty 后,可以在以下 URL 上找到JMXConfigurator(搜索“ ch.qos.logback.classic”):

http://localhost:8082/

下面是 MX4J 界面的屏幕截图。

mx4j_jetty.gif

为 Tomcat 配置 JMX(在 JDK 1.5 和 1.6 下测试)

如果您使用的是 JDK 1.6 及更高版本,则默认情况下您的服务器已启用 JMX,您可以但不必遵循以下步骤。在 JDK 1.5 下,Tomcat 需要在* $ TOMCAT_HOME/bin/catalina.bat/sh * Shell 脚本中添加以下几行:

CATALINA_OPTS="-Dcom.sun.management.jmxremote"

使用这些选项启动后,通过在 shell 中发出以下命令,可以使用jconsole访问 Tomcat 公开的 MBean 以及logback的JMXConfigurator

jconsole

jconsole15_tomcat.gif

构建连接后,您应该可以访问JMXXConfigurator,如上面的screenshot所示。

带有 Tomcat 的 MX4J(在 JDK 1.5 和 1.6 下测试)

您可能希望通过 MX4J 提供的基于 Web 的界面访问 JMX 组件。在这种情况下,以下是必需的步骤:

假设您已经下载了MX4J,请将* mx4j-tools.jar 文件放在 $ TOMCAT_HOME/bin/目录下。然后,将以下行添加到 $ TOMCAT_HOME/bin/catalina.sh *配置文件中:

\ at the beginning of the file CATALINA_OPTS =“-Dcom.sun.management.jmxremote”<!-- in the "Add on extra jar files to CLASSPATH" section --> CLASSPATH =“ $ CLASSPATH”:“ $ CATALINA_HOME” /bin/mx4j-tools.jar

最后,在* $ TOMCAT_HOME/conf/server.xml *文件中声明一个新的Connector

<Connector port="0" 
  handler.list="mx"
  mx.enabled="true" 
  mx.httpHost="localhost" 
  mx.httpPort="8082" 
  protocol="AJP/1.3" />

Tomcat 启动后,应该可以通过将浏览器指向以下 URL(搜索“ ch.qos.logback.classic”)来找到 JMXConfigurator:

http://localhost:8082/

下面是 MX4J 界面的屏幕截图。

mx4j_tomcat.gif