介绍
监控是系统管理的一个关键方面。 查看正在运行的服务器内部、获取一些统计信息或重新配置应用程序的某些方面都是日常管理任务。
启用远程 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 - |
|
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" />