Программный доступ к встроенным MBeans в Tomcat

Поэтому в основном я пытаюсь изменить код из этого руководства здесь: http://docs.oracle.com/javase/tutorial/jmx/remote/custom.html чтобы я мог получить доступ к MBeans из tomcat, которые описаны здесь: http://wiki.apache.org/tomcat/FAQ/Monitoring

нет проблем с доступом к JMX Bean-компоненту java.lang:type=Memory из кода, поскольку его интерфейс определен в java.lang. Вот пример кода этого:

    ObjectName mbeanName = new ObjectName("java.lang:type=Memory");
    MemoryMXBean mxbeanProxy2 = JMX.newMXBeanProxy(mbsc, mbeanName, MemoryMXBean.class, true);
    MemoryUsage memUsage = mxbeanProxy2.getHeapMemoryUsage();
    echo("\nMemory Utilization: " + (memUsage.getUsed()/(double)memUsage.getMax()) * 100 +  "%");

Здесь mbsc является экземпляром MBeanServerConnection. Проблема в том, что когда я пытаюсь получить доступ к встроенным MBean-компонентам в Tomcat аналогичным образом, я сталкиваюсь с проблемой, что не могу найти интерфейс, определенный для любого из MBean-компонентов Tomcat. Я могу отслеживать MBeans из JConsole, но для этого мне нужно быть в состоянии сделать это из кода. Я где-то обнаружил, что это также может быть сделано с чем-то вроде этого:

ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName, "name");

Но это дает мне следующее исключение: Исключение в потоке "main" javax.management.AttributeNotFoundException: Нет такого атрибута: имя в com.sun.jmx.mbeanserver......

Я чувствую, что упускаю что-то довольно простое. Но информация по этому вопросу, как представляется, очень ограничена, и Google не сильно помог.

2 ответа

Решение

Я думаю, что в вашем втором фрагменте кода есть опечатка. Вы создали новое ObjectName для Catalina ThreadPool с именем mbeanName2, но когда вы пытаетесь получить атрибут "name", вы все еще используете mbeanName.

Так и должно быть:

ObjectName mbeanName2 = new ObjectName("Catalina:type=ThreadPool,name=\"http-apr-8080\"");
Object value = mbsc.getAttribute(mbeanName2, "name");

Кроме этого, ваш код должен работать нормально.

Сегодня у меня возникла та же проблема, что и Oz0234, описанный выше (с использованием TomEE 1.7.0 в Windows), но я некоторое время не понимал, почему решение ProxyBean вообще не работает ни с какими объектами Catalina.

Это работает с MBeanServerConnection.Метод getAttribute(objectName, attribute), но он не работает с использованием методов прокси-компонента. Я проверял и проверял много.

Наконец-то я выяснил, почему это происходит. Ответ заключается в том, что имена атрибутов в домене Catalina начинаются со строчной буквы, а имена атрибутов в других доменах (java.lang, java.nio, openejb, ...) начинаются с заглавной буквы, как описано здесь: http://docs.oracle.com/javase/7/docs/api/javax/management/JMX.html

Я извлек самую важную часть:

MyMXBean proxy = JMX.newMXBeanProxy(mbs, name, MyMXBean.class);

Предположим, например, что MyMXBean выглядит так:

public interface MyMXBean {
  public String getSimpleAttribute();
  public void setSimpleAttribute(String value);
  public MemoryUsage getMappedAttribute();
  public void setMappedAttribute(MemoryUsage memoryUsage);
  public MemoryUsage someOperation(String param1, MemoryUsage param2);
}

Then proxy.getSimpleAttribute() will result in a call to
mbs.getAttribute(name, "SimpleAttribute").

Вы можете увидеть в приведенном выше примере, что имя атрибута начинается с заглавной буквы "S" ImpleAttribute в качестве имени получателя прокси-бина getS ImpleAttribute. К сожалению, это прямо противоположно тому, что описывает соглашение о присвоении имен для методов получения / установки bean-компонента.

Также я проверил другие атрибуты Tomcat Domain Objects (Catalina,Users), доступные в соединении JMX, и я также сравнил некоторые другие атрибуты. Если имя атрибута начинается с заглавной буквы, прокси бина работает. Если он начинается со строчной буквы, работает только метод getAttribute, например:

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
try(JMXConnector jmxc = JMXConnectorFactory.connect(url)) {
  MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
  ObjectName mbeanName = new ObjectName("Catalina:type=Manager,context=/,host=localhost");
  Object value = mbsc.getAttribute(mbeanName, "activeSessions");
}

Поэтому вам нужно обратить внимание, какой метод вы выберете.

Другие вопросы по тегам