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

<jmx:open
    url="service:jmx:rmi:///jndi/rmi://localhost:9024/jmxrmi"
    ref="jmx.server.9024"
    username="controlRole"
    password="<password>"
    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="<password>"
        name="Catalina:type=IDataSender,host=localhost,senderAddress=<ip_address>,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="<password>"
        name="Catalina:type=IDataSender,host=localhost,senderAddress=<ip_address>,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.