介绍

监控是系统管理的一个关键方面。 查看正在运行的服务器内部、获取一些统计信息或重新配置应用程序的某些方面都是日常管理任务。

启用远程 JMX

注意:仅当要远程监视 Tomcat 时,才需要此配置。 如果打算使用与 Tomcat 相同的用户在本地监视它,则不需要它。

Oracle 网站包括选项列表以及如何在 Java 11 上配置 JMX Remote: http://docs.oracle.com/javase/6/docs/technotes/guides/management/agent.html。

以下是 Java 11 的快速配置指南:

将以下参数添加到 Tomcat 的`setenv.bat`脚本中(有关详细信息,请参见RUNNING.txt)。

注意:此语法适用于 Microsoft Windows。该命令必须位于同一行。它被包装以使其更具可读性。 如果 Tomcat 作为 Windows 服务运行,请使用其配置对话框为该服务设置 java 选项。 对于 Linux、MacOS 等,请删除行首的 “set”。

set CATALINA_OPTS=-Dcom.sun.management.jmxremote.port=%my.jmx.port%
  -Dcom.sun.management.jmxremote.rmi.port=%my.rmi.port%
  -Dcom.sun.management.jmxremote.ssl=false
  -Dcom.sun.management.jmxremote.authenticate=false

如果不设置 com.sun.management.jmxremote.rmi.port, 则 JSR 160 JMX 适配器将随机选择一个端口,这将可能难以配置防火墙以允许访问。

如果需要 TLS:

  • 更改并添加以下内容:

  -Dcom.sun.management.jmxremote.ssl=true
  -Dcom.sun.management.jmxremote.registry.ssl=true
  • 要配置协议和/或密码套件,请使用:

  -Dcom.sun.management.jmxremote.ssl.enabled.protocols=%my.jmx.ssl.protocols%
  -Dcom.sun.management.jmxremote.ssl.enabled.cipher.suites=%my.jmx.cipher.suites%
  • 要进行客户端证书身份验证,请使用:

  -Dcom.sun.management.jmxremote.ssl.need.client.auth=%my.jmx.ssl.clientauth%

如果需要授权(强烈建议始终将 TLS 与身份验证一起使用):

  • 更改并添加以下内容:

  -Dcom.sun.management.jmxremote.authenticate=true
  -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
  -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
  • 编辑访问授权文件 $CATALINA_BASE/conf/jmxremote.access

monitorRole readonly
controlRole readwrite
  • 编辑密码文件 $CATALINA_BASE/conf/jmxremote.password

monitorRole tomcat
controlRole tomcat

提示: 密码文件应该是只读的,并且只有运行 Tomcat 的操作系统用户才能访问。

  • 或者,可以使用以下命令配置 JAAS 登录模块:

  -Dcom.sun.management.jmxremote.login.config=%login.module.name%

如果需要指定要在发送到客户端的 RMI 存根中使用的主机名 (例如,因为必须用于连接的公共主机名与本地主机名不同),那么可以设置:

set CATALINA_OPTS=-Djava.rmi.server.hostname

如果需要为 JMX 服务指定要绑定到的特定接口,则可以设置:

set CATALINA_OPTS=-Dcom.sun.management.jmxremote.host

使用 JMX 远程 Ant 任务管理 Tomcat

为了简化 Ant 的 JMX 使用,提供了一组可与 antlib 一起使用的任务。

antlib:将 catalina-ant.jar 从 $CATALINA_HOME/lib 复制到 $ANT_HOME/lib。

以下示例显示了 JMX Accessor 的用法:

注意:name 属性值被包装在此处以使其更具可读性。 它必须全部在同一行上,没有空格。

<project name="Catalina Ant JMX"
      xmlns:jmx="antlib:org.apache.catalina.ant.jmx"
      default="state"
      basedir=".">
  <property name="jmx.server.name" value="localhost" />
  <property name="jmx.server.port" value="9012" />
  <property name="cluster.server.address" value="192.168.1.75" />
  <property name="cluster.server.port" value="9025" />

  <target name="state" description="Show JMX Cluster state">
    <jmx:open
      host="${jmx.server.name}"
      port="${jmx.server.port}"
      username="controlRole"
      password="tomcat"/>
    <jmx:get
      name=
"Catalina:type=IDataSender,host=localhost,
senderAddress=${cluster.server.address},senderPort=${cluster.server.port}"
      attribute="connected"
      resultproperty="IDataSender.backup.connected"
      echo="false"
    />
    <jmx:get
      name="Catalina:type=ClusterSender,host=localhost"
      attribute="senderObjectNames"
      resultproperty="senderObjectNames"
      echo="false"
    />
    <!-- get current maxActiveSession from ClusterTest application
       echo it to Ant output and store at
       property <em>clustertest.maxActiveSessions.original</em>
    -->
    <jmx:get
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      attribute="maxActiveSessions"
      resultproperty="clustertest.maxActiveSessions.original"
      echo="true"
    />
    <!-- set maxActiveSession to 100
    -->
    <jmx:set
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      attribute="maxActiveSessions"
      value="100"
      type="int"
    />
    <!-- get all sessions and split result as delimiter <em>SPACE</em> for easy
       access all session ids directly with Ant property sessions.[0..n].
    -->
    <jmx:invoke
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      operation="listSessionIds"
      resultproperty="sessions"
      echo="false"
      delimiter=" "
    />
    <!-- Access session attribute <em>Hello</em> from first session.
    -->
    <jmx:invoke
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      operation="getSessionAttribute"
      resultproperty="Hello"
      echo="false"
    >
      <arg value="${sessions.0}"/>
      <arg value="Hello"/>
    </jmx:invoke>
    <!-- Query for all application manager.of the server from all hosts
       and bind all attributes from all found manager MBeans.
    -->
    <jmx:query
      name="Catalina:type=Manager,*"
      resultproperty="manager"
      echo="true"
      attributebinding="true"
    />
    <!-- echo the create properties -->
<echo>
senderObjectNames: ${senderObjectNames.0}
IDataSender.backup.connected: ${IDataSender.backup.connected}
session: ${sessions.0}
manager.length: ${manager.length}
manager.0.name: ${manager.0.name}
manager.1.name: ${manager.1.name}
hello: ${Hello}
manager.ClusterTest.0.name: ${manager.ClusterTest.0.name}
manager.ClusterTest.0.activeSessions: ${manager.ClusterTest.0.activeSessions}
manager.ClusterTest.0.counterSend_EVT_SESSION_EXPIRED:
 ${manager.ClusterTest.0.counterSend_EVT_SESSION_EXPIRED}
manager.ClusterTest.0.counterSend_EVT_GET_ALL_SESSIONS:
 ${manager.ClusterTest.0.counterSend_EVT_GET_ALL_SESSIONS}
</echo>

  </target>

</project>

import:使用 <import file=“${CATALINA.HOME}/bin/catalina-tasks.xml” /> 导入 JMX 访问器项目,并使用 jmxOpen、jmxSet、jmxGet、jmxQuery、jmxInvoke、jmxEquals 和 jmxCondition 引用任务。

JMXAccessorOpenTask - JMX 打开连接任务

属性列表

属性 Attribute 说明 Description

默认值 Default value

url

设置 JMX 连接 URL - service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi

host

设置 host,快捷键很长的 URL 语法。

localhost

port

设置远程连接端口

8050

username

远程 JMX 连接用户名

password

远程 JMX 连接密码

ref

内部连接引用的名称。使用此属性,可以在同一 Ant 项目中配置多个连接

jmx.server

echo

Echo 命令用法(用于访问分析或调试)

false

if

仅当前项目中存在给定名称的属性时执行

unless

仅当前项目中不存在给定名称的属性时执行

打开新 JMX 连接的示例

  <jmx:open
    host="${jmx.server.name}"
    port="${jmx.server.port}"
  />

从 URL 打开 JMX 连接的示例,并在其他引用处进行授权和存储

  <jmx:open
    url="service:jmx:rmi:///jndi/rmi://localhost:9024/jmxrmi"
    ref="jmx.server.9024"
    username="controlRole"
    password="tomcat"
  />

从 URL 打开 JMX 连接的示例,授权并存储在其他引用中, 但仅当属性 jmx.if 存在 和 jmx.unless 不存在时

  <jmx:open
    url="service:jmx:rmi:///jndi/rmi://localhost:9024/jmxrmi"
    ref="jmx.server.9024"
    username="controlRole"
    password="tomcat"
    if="jmx.if"
    unless="jmx.unless"
  />

jmxOpen 任务中的所有属性也存在于所有其他任务和条件下。

JMXAccessorGetTask:获取属性值 Ant 任务

属性列表

属性 Attribute 说明 Description

默认值 Default value

name

完全限定的 JMX ObjectName — Catalina:type=Server

attribute

现有 MBean 属性(请参阅上面的 Tomcat MBean 描述)

ref

JMX 连接参考

jmx.server

echo

Echo 命令用法(访问和结果)

false

resultproperty

在此项目属性处保存结果

delimiter

使用分隔符 (java.util.StringTokenizer) 拆分结果,并使用 resultproperty 作为前缀来存储令牌

separatearrayresults

当返回值为数组时,将结果保存为属性列表 ($resultproperty.[0..N] 和 $resultproperty.length)

true

从默认 JMX 连接获取远程 MBean 属性的示例

  <jmx:get
    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
    attribute="maxActiveSessions"
    resultproperty="servlets-examples.maxActiveSessions"
  />

获取和结果数组并在单独的属性中拆分它的示例

  <jmx:get
      name="Catalina:type=ClusterSender,host=localhost"
      attribute="senderObjectNames"
      resultproperty="senderObjectNames"
  />

使用以下命令访问 senderObjectNames 属性:

  ${senderObjectNames.length} give the number of returned sender list.
  ${senderObjectNames.[0..N]} found all sender object names

仅在配置群集时获取 IDataSender 属性连接的示例。

注意:name 属性值被包装在此处以使其更具可读性。它必须全部在同一行上,没有空格。

  <jmx:query
    failonerror="false"
    name="Catalina:type=Cluster,host=${tomcat.application.host}"
    resultproperty="cluster"
  />
  <jmx:get
    name=
"Catalina:type=IDataSender,host=${tomcat.application.host},
senderAddress=${cluster.backup.address},senderPort=${cluster.backup.port}"
    attribute="connected"
    resultproperty="datasender.connected"
    if="cluster.0.name" />