- イントロダクション
- JMX Remote の有効化
- JMX remote Ant タスクによる Tomcat の管理
- JMXAccessorOpenTask - JMX オープン接続タスク
- JMXAccessorGetTask: 属性値取得 Ant タスク
- JMXAccessorSetTask: 属性値設定 Ant タスク
- JMXAccessorInvokeTask: MBean 操作実行 Ant タスク
- JMXAccessorQueryTask: MBean クエリ Ant タスク
- JMXAccessorCreateTask: リモート MBean 作成 Ant タスク
- JMXAccessorUnregisterTask: リモート MBean 登録解除 Ant タスク
- JMXAccessorCondition: 条件式
- JMXAccessorEqualsCondition: equals MBean Ant 条件
- JMXProxyServlet の使用
Tomcat の監視と管理
目次
イントロダクション
監視はシステム管理の重要な側面です。 実行中のサーバー内部を調べたり、統計情報を取得したり、アプリケーションの側面を再構成したりすることは、すべて日常的な管理タスクです。
JMX Remote の有効化
注: この構成は、Tomcat をリモートで監視する場合にのみ必要です。 Tomcat が実行されているのと同じユーザーを使用してローカルで監視する場合は必要ありません。
Oracle の Web サイトには、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-Adaptor はランダムなポートを選択するため、アクセスを許可するようにファイアウォールを構成するのが難しくなる可能性があります。
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 remote 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 Accessor プロジェクトをインポートし、jmxOpen、jmxSet、jmxGet、jmxQuery、jmxInvoke、jmxEquals、および jmxCondition でタスクを参照します。
JMXAccessorOpenTask - JMX オープン接続タスク
属性のリスト
属性 | 説明 | デフォルト値 |
---|---|---|
url | JMX 接続 URL を設定します - service:jmx:rmi:///jndi/rmi://: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://:9024/jmxrmi"
ref="jmx.server.9024"
username="controlRole"
password="tomcat"
/>
URL から JMX 接続を開き、認証して別の参照に格納する例 (ただし、プロパティ jmx.if が存在し、jmx.unless が存在しない場合にのみ)
<jmx:open
url="service:jmx:rmi:///jndi/rmi://: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) で結果を分割し、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" />
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) で結果を分割し、resultproperty をトークンを格納するためのプレフィックスとして使用します。 | |
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>
vhost 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) で結果を分割し、resultproperty をトークンを格納するためのプレフィックスとして使用します。 | |
separatearrayresults | 戻り値が配列の場合、結果をプロパティリストとして保存します ($resultproperty.[0..N] および $resultproperty.length) | true |
すべてのサービスとホストからすべての Manager 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 attribute names]} でこのマネージャーのすべてのプロパティにアクセスできます。 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 は、一度
作成すると、親にリンクできません。 Valve、Cluster、Realm MBean は自動的に
親に接続されません。 代わりに、MBeanFactory 作成
操作を使用します。
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
削除操作を使用します。
JMXAccessorCondition: 条件式
属性のリスト
属性 | 説明 | デフォルト値 |
---|---|---|
url | JMX 接続 URL を設定します - service:jmx:rmi:///jndi/rmi://: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: equals MBean Ant 条件
属性のリスト
属性 | 説明 | デフォルト値 |
---|---|---|
url | JMX 接続 URL を設定します - service:jmx:rmi:///jndi/rmi://: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 を直接使用するよりも、次の利点があります
- 実行中のサーバーから小さなデータを 1 つ要求するだけで、完全な JVM を起動してリモート JMX 接続を確立する必要はありません。
- JMX 接続の操作方法を知る必要はありません
- このページの残りの部分で説明されている複雑な構成は必要ありません
- クライアントプログラムを Java で記述する必要はありません
JMX の過剰な使用の完璧な例は、Nagios や Icinga などの一般的なサーバー監視ソフトウェアの場合に見られます。JMX 経由で 10 個の項目を監視する場合、10 個の JVM を起動し、10 個の JMX 接続を確立してから、すべてを数分ごとにシャットダウンする必要があります。 JMXProxyServlet を使用すると、10 個の HTTP 接続を確立して完了することができます。
JMXProxyServlet の詳細については、Tomcat マネージャーのドキュメントを参照してください。