Мониторинг Tomcat#

Включение удаленного доступа к JMX#

Данная конфигурация необходима, если требуется удаленный мониторинг Tomcat.

Ниже приведен пример настройки для Java.

Добавьте следующие параметры в скрипт setenv.bat:

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 выполните следующие шаги:

  1. Измените и добавьте следующие параметры:

    -Dcom.sun.management.jmxremote.ssl=true
    -Dcom.sun.management.jmxremote.registry.ssl=true
    
  2. Для настройки протоколов и/или наборов шифров используйте:

    -Dcom.sun.management.jmxremote.ssl.enabled.protocols=%my.jmx.ssl.protocols%
    -Dcom.sun.management.jmxremote.ssl.enabled.cipher.suites=%my.jmx.cipher.suites%
    
  3. Для аутентификации с использованием клиентского сертификата добавьте:

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

Настройка аутентификации#

Если требуется аутентификация (настоятельно рекомендуется всегда использовать TLS вместе с аутентификацией):

  1. Измените и добавьте следующие параметры:

    -Dcom.sun.management.jmxremote.authenticate=true
    -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password
    -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
    
  2. Отредактируйте файл авторизации доступа $CATALINA_BASE/conf/jmxremote.access:

    monitorRole readonly
    controlRole readwrite
    
  3. Отредактируйте файл паролей $CATALINA_BASE/conf/jmxremote.password:

    monitorRole tomcat
    controlRole tomcat
    

    Файл паролей должен быть доступен только для чтения и только для пользователя операционной системы, под которым запущен Tomcat.

  4. Опционально: настройте модуль входа JAAS:

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

Указание имени хоста для RMI#

Если необходимо указать имя хоста для в RMI-заглушек, отправляемых клиенту (например, если публичное имя хоста, используемое для подключения, отличается от локального имени хоста), установите:

set CATALINA_OPTS=-Djava.rmi.server.hostname=%public.host.name%

Для указания конкретного интерфейса для связи с JMX-сервисом установите:

set CATALINA_OPTS=-Dcom.sun.management.jmxremote.host=%interface.ip.address%

Управление Tomcat с помощью удаленного Ant Tasks через JMX#

Для упрощения использования JMX с Ant предоставляется набор задач, которые можно использовать с 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="<IP_address>" />
  <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"
    />
     # получаем текущую максимальную активность сеанса из приложения для тестирования кластера
     # преобразуем ее в выходные данные Ant и сохраняем по адресу
     # свойства <em>clustertest.maxActiveSessions.original</em>
    <jmx:get
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      attribute="maxActiveSessions"
      resultproperty="clustertest.maxActiveSessions.original"
      echo="true"
    />
     # устанавливаем значение maxActiveSession до 100
    <jmx:set
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      attribute="maxActiveSessions"
      value="100"
      type="int"
    />
     # получаем все сеансы и делим результат в виде разделителя <em>SPACE</em> для удобства
     # получаем доступ ко всем идентификаторам сеансов напрямую с помощью Ant property sessions.[0..n].
    <jmx:invoke
      name="Catalina:type=Manager,context=/ClusterTest,host=localhost"
      operation="listSessionIds"
      resultproperty="sessions"
      echo="false"
      delimiter=" "
    />
     # получаем доступ к атрибуту сеанса <em>Hello</em> из первого сеанса.
    <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>
     # запрашиваем все управляющие приложениями сервера со всех хостов
     # и привязываем все атрибуты из всех средств управления фондами.
    <jmx:query
      name="Catalina:type=Manager,*"
      resultproperty="manager"
      echo="true"
      attributebinding="true"
    />
     # echo создает свойства
<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>

JMXAccessorOpenTask#

JMXAccessorOpenTask используется для открытия соединения с JMX-сервером.

В таблице ниже приведены атрибуты JMXAccessorOpenTask.

Атрибуты JMXAccessorOpenTask#

Атрибут

Описание

Значение по умолчанию

url

Устанавливает URL для подключения к JMX

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}"
/>
  • Чтобы открыть соединения JMX по URL с авторизацией и сохранением в другой ссылке, используйте:

<jmx:open
    url="service:jmx:rmi:///jndi/rmi://localhost:9024/jmxrmi"
    ref="jmx.server.9024"
    username="controlRole"
    password="tomcat"
/>
  • Чтобы открыть соединения JMX по URL с авторизацией и сохранением в другой ссылке, используя свойствоjmx.if, настройте:

<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"
/>

JMXAccessorGetTask#

JMXAccessorGetTask используется для получения значения атрибута MBean через JMX.

В таблице ниже приведены атрибуты JMXAccessorGetTask

Список атрибутов JMXAccessorGetTask#

Атрибут

Описание

Значение по умолчанию

name

Полное имя JMX ObjectName

attribute

Существующий атрибут MBean

ref

Ссылка на соединение JMX

jmx.server

echo

Вывод команды (доступ и результат)

false

resultproperty

Сохранение результата в указанное свойство проекта

delimiter

Разделение результата и сохранение токенов с префиксом resultproperty

separatearrayresults

Сохранение результата в качестве списка свойств

true

Примеры использования#

  • Для получения атрибута MBean из удаленного соединения JMX настройте:

<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} — количество возвращенных отправителей;

    • {senderObjectNames.[0..N]} — имена всех отправителей.

JMXAccessorSetTask#

JMXAccessorSetTask используется для установки значения атрибута MBean через JMX.

В таблице ниже приведены атрибуты JMXAccessorSetTask

Список атрибутов JMXAccessorSetTask#

Атрибут

Описание

Значение по умолчанию

name

Полное имя JMX ObjectName

attribute

Существующий атрибут 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#

JMXAccessorInvokeTask используется для вызова операции MBean через JMX.

В таблице ниже приведены атрибуты JMXAccessorInvokeTask

Список атрибутов JMXAccessorInvokeTask#

Атрибут

Описание

Значение по умолчанию

name

Полное имя JMX ObjectName

operation

Существующая операция MBean

ref

Ссылка на соединение JMX

jmx.server

echo

Вывод команды (доступ и результат)

false

resultproperty

Сохранение результата в указанное свойство проекта

delimiter

Разделение результата и сохранение токена с префиксом resultproperty

separatearrayresults

Сохранение результата в качестве списка свойств

true

Примеры использования#

  • Чтобы остановить приложение, используйте:

<jmx:invoke
    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
    operation="stop"
/>
  • Чтобы получить все идентификаторы сессий, используйте:

<jmx:invoke
    name="Catalina:type=Manager,context=/servlets-examples,host=localhost"
    operation="listSessionIds"
    resultproperty="sessions"
    delimiter=" "
/>

Теперь идентификаторы сессий находятся в свойствах ${sessions.[0..N], а количество — в ${sessions.length}.

JMXAccessorQueryTask#

JMXAccessorQueryTask используется для запроса MBean через JMX.

В таблице ниже приведены атрибуты ``JMXAccessorQueryTask`

Список атрибутов JMXAccessorQueryTask#

Атрибут

Описание

Значение по умолчанию

name

Строка запроса JMX ObjectName

ref

Ссылка на соединение JMX

jmx.server

echo

Вывод команды (доступ и результат)

false

resultproperty

Префикс для сохранения всех найденных MBean

attributebinding

Привязка всех атрибутов MBean в дополнение к имени

false

delimiter

Разделение результата и сохранение токенов с префиксом resultproperty

separatearrayresults

Сохранение результата в качестве списка свойств

true

Примеры использования#

Для получения всех ObjectName для Manager введите:

<jmx:query
    name="Catalina:type=Manager,*"
    resultproperty="manager"
/>

Теперь имена менеджеров находятся в свойствах ${manager.[0..N].name, а количество — в ${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">
        # Настройка соединения 
        <jmx:open
            host="${jmx.host}"
            port="${jmx.port}"
            ref="jmx.server"
            username="${jmx.username}"
            password="${jmx.password}"/>

        # Запрос списка MBean 
        <jmx:query
            name="*:*"
            resultproperty="mbeans"
            attributebinding="false"/>

        # Сохранение результатов в XML-файл 
        <echoproperties
            destfile="mbeans.properties"
            prefix="mbeans."
            format="xml"/>

        # Вывод результатов 
        <echo message="Number of MBeans in server ${jmx.host}:${jmx.port} is ${mbeans.length}"/>
    </target>
</project>

JMXAccessorCreateTask#

JMXAccessorCreateTask используется для удаленного создания MBean.

В таблице ниже приведены атрибуты JMXAccessorCreateTask

Список атрибутов JMXAccessorQueryTask#

Атрибут

Описание

Значение по умолчанию

name

Полное имя JMX ObjectName

className

Полное имя класса MBean

classLoader

ObjectName серверного или веб-приложения ClassLoader

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>

MBean для Valve, Cluster и Realm не подключаются автоматически. Используйте create из MBeanFactory.

JMXAccessorUnregisterTask#

JMXAccessorUnregisterTask используется для удаленной отмены регистрации MBean.

В таблице ниже приведены атрибуты JMXAccessorUnregisterTask.

Список атрибутов JMXAccessorUnregisterTask#

Атрибут

Описание

Значение по умолчанию

name

Полное имя JMX ObjectName

ref

Ссылка на соединение JMX

jmx.server

echo

Вывод команды (доступ и результат)

false

Пример использования#

Для удаленной отмены регистрации MBean используйте:

<jmx:unregister
    name="Catalina:type=MBeanFactory"
/>

Многие MBean Tomcat не могут быть отменены. Используйте remove из MBeanFactory.

JMXAccessorCondition#

JMXAccessorCondition используется для проверки условий на основе атрибутов MBean.

В таблице ниже приведены атрибуты JMXAccessorCondition.

Список атрибутов JMXAccessorCondition#

Атрибут

Описание

Значение по умолчанию

url

Устанавливает URL для подключения к JMX

host

Устанавливает хост для подключения. Упрощает длинный синтаксис URL

localhost

port

Устанавливает порт для удаленного подключения

8050

username

Устанавливает имя пользователя для удаленного подключения JMX

password

Устанавливает пароль для удаленного подключения JMX

ref

Устанавливает имя внутренней ссылки на соединение. Позволяет настроить несколько соединений в одном проекте Ant

jmx.server

name

Выводит полное имя JMX ObjectName

echo

Выводит использование команды (доступ и результат)

false

if

Выполняет задачу только если свойство с указанным именем существует в текущем проекте

unless

Выполняет задачу только если свойство с указанным именем не существует в текущем проекте

value

Дополняет второй аргумент для операции

type

Задает тип значения для выражения операции (поддерживаются long и double)

long

operation

Устанавливает операцию для сравнения: == (равно), != (не равно), > (больше), >= (больше или равно), < (меньше), <= (меньше или равно)

==

Пример использования#

Чтобы запустить node резервного копирования кластера, используйте:

<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=000.000.000.0,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#

JMXAccessorEqualsCondition используется для проверки равенства атрибутов MBean.

В таблице ниже приведены атрибуты JMXAccessorEqualsCondition.

Список атрибутов JMXAccessorEqualsCondition#

Атрибут

Описание

Значение по умолчанию

url

Устанавливает URL для подключения к JMX

host

Устанавливает хост для подключения. Упрощает длинный синтаксис URL

localhost

port

Устанавливает порт для удаленного подключения

8050

username

Устанавливает имя пользователя для удаленного подключения JMX

password

Устанавливает пароль для удаленного подключения JMX

ref

Устанавливает имя внутренней ссылки на соединение. Позволяет настроить несколько соединений в одном проекте Ant

jmx.server

name

Выводит полное имя JMX ObjectName

echo

Выводит использование команды (доступ и результат)

false

Пример использования#

Чтобы запустить node резервного копирования кластера, используйте:

<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=000.000.000.0,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 через HTTP-интерфейс: JMXProxyServlet.

JMXProxyServlet позволяет выполнять JMX-запросы через HTTP. Этот подход имеет следующие преимущества перед использованием JMX напрямую:

  1. Не нужно запускать JVM и устанавливать удаленное JMX-соединение только для получения одного небольшого фрагмента данных.

  2. Не нужно знать, как работать с JMX-соединениями.

  3. Не требуется сложная конфигурация.

  4. Клиентская программа не обязана быть написана на Java.

Идеальный пример использования JMXProxyServlet — это мониторинг серверов с помощью таких инструментов, как Nagios или Icinga.