- はじめに
- JMXリモートの有効化
- JMXリモートAntタスクを使用したTomcatの管理
- JMXAccessorOpenTask - JMX接続オープンタスク
- JMXAccessorGetTask: 属性値取得Antタスク
- JMXAccessorSetTask: 属性値設定Antタスク
- JMXAccessorInvokeTask: MBean操作呼び出しAntタスク
- JMXAccessorQueryTask: MBeanクエリAntタスク
- JMXAccessorCreateTask: リモートMBean作成Antタスク
- JMXAccessorUnregisterTask: リモートMBean登録解除Antタスク
- JMXAccessorCondition: 条件式
- JMXAccessorEqualsCondition: MBean等価条件Ant条件
- JMXProxyServletの使用
Tomcatの監視と管理
目次
はじめに
監視はシステム管理の重要な側面です。稼働中のサーバー内部を調べたり、統計情報を取得したり、アプリケーションのいくつかの側面を再構成したりすることは、すべて毎日の管理タスクです。
JMXリモートの有効化
注記: この設定は、Tomcatをリモートで監視する場合にのみ必要です。Tomcatが実行されているのと同じユーザーを使用してローカルで監視する場合は、必要ありません。
Oracleのウェブサイトには、Java 11でJMXリモートを設定する方法とオプションの一覧があります。 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`を編集します。ヒント: パスワードファイルは読み取り専用にし、Tomcatが実行されているオペレーティングシステムユーザーのみがアクセスできるようにする必要があります。
monitorRole tomcat controlRole 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_HOME/lib`から`$ANT_HOME/lib`に`catalina-ant.jar`をコピーします。
次の例は、JMXアクセサの使用を示しています。
注記: `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 file="${CATALINA.HOME}/bin/catalina-tasks.xml" />`でJMXアクセサプロジェクトをインポートし、`jmxOpen`、`jmxSet`、`jmxGet`、`jmxQuery`、`jmxInvoke`、`jmxEquals`、`jmxCondition`を使用してタスクを参照します。
JMXAccessorOpenTask - JMX接続オープンタスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
url | JMX接続URLを設定します - `service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi` | |
host | ホストを設定し、非常に長いURL構文を短縮します。 | localhost |
port | リモート接続ポートを設定します | 8050 |
username | リモートJMX接続のユーザー名。 | |
password | リモートJMX接続のパスワード。 | |
ref | 内部接続参照の名前。この属性を使用すると、同じAntプロジェクト内で複数の接続を設定できます。 | jmx.server |
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タスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
name | 完全修飾JMX ObjectName -- `Catalina:type=Server` | |
attribute | 既存のMBean属性(上記のTomcat MBeanの説明を参照) | |
ref | JMX接続参照 | jmx.server |
echo | コマンドの使用状況を出力します(アクセスと結果) | false |
resultproperty | 結果をこのプロジェクトプロパティに保存します | |
delimiter | デリミタ(`java.util.StringTokenizer`)で結果を分割し、結果プロパティをプレフィックスとして使用してトークンを保存します。 | |
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" />
JMXAccessorSetTask: 属性値設定Antタスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
name | 完全修飾JMX ObjectName -- `Catalina:type=Server` | |
attribute | 既存のMBean属性(上記のTomcat MBeanの説明を参照) | |
value | 属性に設定する値 | |
type | 属性の型。 | `java.lang.String` |
ref | JMX接続参照 | jmx.server |
echo | コマンドの使用状況を出力します(アクセスと結果) | false |
リモートMBean属性値を設定する例
<jmx:set
name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
attribute="maxActiveSessions"
value="500"
type="int"
/>
JMXAccessorInvokeTask: MBean操作呼び出しAntタスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
name | 完全修飾JMX ObjectName -- `Catalina:type=Server` | |
operation | 既存のMBean操作 | |
ref | JMX接続参照 | jmx.server |
echo | コマンドの使用状況を出力します(アクセスと結果) | false |
resultproperty | 結果をこのプロジェクトプロパティに保存します | |
delimiter | デリミタ(`java.util.StringTokenizer`)で結果を分割し、結果プロパティをプレフィックスとして使用してトークンを保存します。 | |
separatearrayresults | 戻り値が配列の場合、結果をプロパティリストとして保存します(`$resultproperty.[0..N]`と`$resultproperty.length`) | true |
アプリケーションを停止する
<jmx:invoke
name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
operation="stop"/>
これで、`${sessions.[0..N}`プロパティで`sessionid`を見つけることができ、`${sessions.length}`プロパティでカウントにアクセスできます。
すべての`sessionid`を取得する例
<jmx:invoke
name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
operation="listSessionIds"
resultproperty="sessions"
delimiter=" "
/>
これで、`${sessions.[0..N}`プロパティで`sessionid`を見つけることができ、`${sessions.length}`プロパティでカウントにアクセスできます。
セッション`${sessionid.0}`からリモートMBeanセッション属性を取得する例
<jmx:invoke
name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
operation="getSessionAttribute"
resultproperty="hello">
<arg value="${sessionid.0}"/>
<arg value="Hello" />
</jmx:invoke>
仮想ホスト`localhost`に新しいアクセスロガーバルブを作成する例
<jmx:invoke
name="Catalina:type=MBeanFactory"
operation="createAccessLoggerValve"
resultproperty="accessLoggerObjectName"
>
<arg value="Catalina:type=Host,host=localhost"/>
</jmx:invoke>
これで、`${accessLoggerObjectName}`プロパティに格納されている名前で新しいMBeanを見つけることができます。
JMXAccessorQueryTask: MBeanクエリAntタスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
name | JMX ObjectNameクエリ文字列 -- `Catalina:type=Manager,*` | |
ref | JMX接続参照 | jmx.server |
echo | コマンドの使用状況を出力します(アクセスと結果) | false |
resultproperty | 検出されたすべてのMBeanにプロジェクトプロパティ名をプレフィックスとして付けます(`mbeans.[0..N].objectname`) | |
attributebinding | `name`に加えて、すべてのMBean属性をバインドします | false |
delimiter | デリミタ(`java.util.StringTokenizer`)で結果を分割し、結果プロパティをプレフィックスとして使用してトークンを保存します。 | |
separatearrayresults | 戻り値が配列の場合、結果をプロパティリストとして保存します(`$resultproperty.[0..N]`と`$resultproperty.length`) | true |
すべてのサービスとホストからすべてのマネージャーObjectNameを取得します
<jmx:query
name="Catalina:type=Manager,*
resultproperty="manager" />
これで、`${manager.[0..N].name}`プロパティでセッションマネージャーを見つけることができ、`${manager.length}`プロパティで結果オブジェクトカウンターにアクセスできます。
`servlet-examples`アプリケーションからマネージャーを取得し、すべてのMBeanプロパティをバインドする例
<jmx:query
name="Catalina:type=Manager,context=/servlet-examples,host=localhost*"
attributebinding="true"
resultproperty="manager.servletExamples" />
これで、`${manager.servletExamples.0.name}`プロパティでマネージャーを見つけることができ、`${manager.servletExamples.0.[manager属性名]}`でこのマネージャーのすべてのプロパティにアクセスできます。MBeanの結果オブジェクトカウンターは`${manager.length}`プロパティに保存されます。
サーバーからすべてのMBeanを取得し、外部XMLプロパティファイルに格納する例
<project name="jmx.query"
xmlns:jmx="antlib:org.apache.catalina.ant.jmx"
default="query-all" basedir=".">
<property name="jmx.host" value="localhost"/>
<property name="jmx.port" value="8050"/>
<property name="jmx.username" value="controlRole"/>
<property name="jmx.password" value="tomcat"/>
<target name="query-all" description="Query all MBeans of a server">
<!-- Configure connection -->
<jmx:open
host="${jmx.host}"
port="${jmx.port}"
ref="jmx.server"
username="${jmx.username}"
password="${jmx.password}"/>
<!-- Query MBean list -->
<jmx:query
name="*:*"
resultproperty="mbeans"
attributebinding="false"/>
<echoproperties
destfile="mbeans.properties"
prefix="mbeans."
format="xml"/>
<!-- Print results -->
<echo message=
"Number of MBeans in server ${jmx.host}:${jmx.port} is ${mbeans.length}"/>
</target>
</project>
これで、`mbeans.properties`ファイル内のすべてのMBeanを見つけることができます。
JMXAccessorCreateTask: リモートMBean作成Antタスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
name | 完全修飾JMX ObjectName -- `Catalina:type=MBeanFactory` | |
className | 既存のMBeanの完全修飾クラス名(上記のTomcat MBeanの説明を参照) | |
classLoader | サーバーまたはWebアプリケーションクラスローダーのObjectName (`Catalina:type=ServerClassLoader,name=[server,common,shared]`または `Catalina:type=WebappClassLoader,context=/myapps,host=localhost`) |
|
ref | JMX接続参照 | jmx.server |
echo | コマンドの使用状況を出力します(アクセスと結果) | false |
リモートMBeanを作成する例
<jmx:create
ref="${jmx.reference}"
name="Catalina:type=MBeanFactory"
className="org.apache.commons.modeler.BaseModelMBean"
classLoader="Catalina:type=ServerClassLoader,name=server">
<arg value="org.apache.catalina.mbeans.MBeanFactory" />
</jmx:create>
警告: 作成された多くのTomcat MBeanは、親にリンクできません。
バルブ、クラスタ、レルムMBeanは、親に自動的に
接続されません。代わりに`MBeanFactory` create
操作を使用してください。
JMXAccessorUnregisterTask: リモートMBean登録解除Antタスク
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
name | 完全修飾JMX ObjectName -- `Catalina:type=MBeanFactory` | |
ref | JMX接続参照 | jmx.server |
echo | コマンドの使用状況を出力します(アクセスと結果) | false |
リモートMBeanの登録を解除する例
<jmx:unregister
name="Catalina:type=MBeanFactory"
/>
警告: 多くのTomcat MBeanは登録解除できません。
MBeanは親からリンク解除されません。代わりに`MBeanFactory`
remove操作を使用してください。
JMXAccessorCondition: 条件式
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
url | JMX接続URLを設定します - `service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi` | |
host | ホストを設定し、非常に長いURL構文を短縮します。 | localhost |
port | リモート接続ポートを設定します | 8050 |
username | リモートJMX接続のユーザー名。 | |
password | リモートJMX接続のパスワード。 | |
ref | 内部接続参照の名前。この属性を使用すると、同じAntプロジェクト内で複数の接続を設定できます。 | jmx.server |
name | 完全修飾JMX ObjectName -- `Catalina:type=Server` | |
echo | 条件の使用状況を出力します(アクセスと結果) | false |
if | 現在のプロジェクトに指定された名前の属性が存在する場合にのみ実行されます。 | |
unless | 現在のプロジェクトに指定された名前の属性が存在しない場合にのみ実行されます。 | |
value (必須) | 操作の第2引数 | |
type | 操作を表す値の型(`long`と`double`をサポート) | long |
operation | 式1
|
== |
サーバー接続とクラスタバックアップノードへのアクセスを待機します
<target name="wait">
<waitfor maxwait="${maxwait}" maxwaitunit="second" timeoutproperty="server.timeout" >
<and>
<socket server="${server.name}" port="${server.port}"/>
<http url="${url}"/>
<jmx:condition
operation="=="
host="localhost"
port="9014"
username="controlRole"
password="tomcat"
name=
"Catalina:type=IDataSender,host=localhost,senderAddress=192.168.111.1,senderPort=9025"
attribute="connected"
value="true"
/>
</and>
</waitfor>
<fail if="server.timeout" message="Server ${url} don't answer inside ${maxwait} sec" />
<echo message="Server ${url} alive" />
</target>
JMXAccessorEqualsCondition: MBean等価条件Ant条件
属性一覧
属性 | 説明 | デフォルト値 |
---|---|---|
url | JMX接続URLを設定します - `service:jmx:rmi:///jndi/rmi://localhost:8050/jmxrmi` | |
host | ホストを設定し、非常に長いURL構文を短縮します。 | localhost |
port | リモート接続ポートを設定します | 8050 |
username | リモートJMX接続のユーザー名。 | |
password | リモートJMX接続のパスワード。 | |
ref | 内部接続参照の名前。この属性を使用すると、同じAntプロジェクト内で複数の接続を設定できます。 | jmx.server |
name | 完全修飾JMX ObjectName -- `Catalina:type=Server` | |
echo | 条件の使用状況を出力します(アクセスと結果) | false |
サーバー接続とクラスタバックアップノードへのアクセスを待機します
<target name="wait">
<waitfor maxwait="${maxwait}" maxwaitunit="second" timeoutproperty="server.timeout" >
<and>
<socket server="${server.name}" port="${server.port}"/>
<http url="${url}"/>
<jmx:equals
host="localhost"
port="9014"
username="controlRole"
password="tomcat"
name=
"Catalina:type=IDataSender,host=localhost,senderAddress=192.168.111.1,senderPort=9025"
attribute="connected"
value="true"
/>
</and>
</waitfor>
<fail if="server.timeout" message="Server ${url} don't answer inside ${maxwait} sec" />
<echo message="Server ${url} alive" />
</target>
JMXProxyServletの使用
Tomcatは、リモート(またはローカル)JMX接続を使用する代わりに、JMXが提供するすべての機能にアクセスできる代替手段を提供します。TomcatのJMXProxyServletです。
JMXProxyServletを使用すると、クライアントはHTTPインターフェースを介してJMXクエリを発行できます。この方法は、クライアントプログラムから直接JMXを使用するよりも、次のような利点があります。
- 稼働中のサーバーから少量のデータだけを要求するために、完全なJVMを起動してリモートJMX接続を行う必要はありません。
- JMX接続の使用方法を知る必要はありません。
- このページの残りの部分で説明されている複雑な設定は必要ありません。
- クライアントプログラムをJavaで記述する必要はありません。
NagiosやIcingaなどの一般的なサーバー監視ソフトウェアの場合、JMXを介して10個のアイテムを監視する場合、10個のJVMを起動し、10個のJMX接続を行い、数分ごとにすべてをシャットダウンする必要があります。JMXProxyServletを使用すると、10個のHTTP接続を行い、それで済みます。
Tomcatマネージャーのドキュメントで、JMXProxyServletの詳細を確認できます。