Виклик методу JMX MBean із сценарію оболонки


98

Чи є бібліотеки, які дозволяли б мені викликати метод JMX MBean із скрипту оболонки. Ми виставляємо деякі команди операцій / адміністратора через JMX, і ми можемо змусити наших адміністраторів використовувати JConsole або VisualVM, але деякі завдання краще залишити для автоматизації. У цій автоматизації ми хотіли б мати можливість викликати метод JMX MBean на нашому запущеному сервері, бажано з сценарію оболонки.

Відповіді:


106

Доступні наступні утиліти JMX командного рядка:

  1. jmxterm - здається, найбільш повнофункціональна програма.
  2. cmdline-jmxclient - використовується у проекті WebArchive, здається, голі кістки (і немає розробки з 2006 року)
  3. Groovy скрипт і JMX - надає дійсно потужний JMX функціонал, але вимагає groovy та іншої бібліотеки.
  4. Функціональність командного рядка JManage - (недоліком є ​​те, що він вимагає запущеного сервера JManage для проксі-команди через)

Приклад Groovy JMX:

import java.lang.management.*
import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory as JmxFactory
import javax.management.remote.JMXServiceURL as JmxUrl

def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:9003/jmxrmi'
String beanName = "com.webwars.gameplatform.data:type=udmdataloadsystem,id=0"
def server = JmxFactory.connect(new JmxUrl(serverUrl)).MBeanServerConnection
def dataSystem = new GroovyMBean(server, beanName)

println "Connected to:\n$dataSystem\n"

println "Executing jmxForceRefresh()"
dataSystem.jmxForceRefresh();

Приклад cmdline-jmxclient:

Якщо у вас є

  • MBean: com.company.data:type=datasystem,id=0

Операція під назвою:

  • jmxForceRefresh ()

Тоді ви можете написати простий скрипт bash (якщо припустити, що ви завантажите cmdline-jmxclient-0.10.3.jar і помістите в ту саму директорію, що і ваш сценарій):

#!/bin/bash

cmdLineJMXJar=./cmdline-jmxclient-0.10.3.jar
user=yourUser
password=yourPassword
jmxHost=localhost
port=9003

#No User and password so pass '-'
echo "Available Operations for com.company.data:type=datasystem,id=0"
java -jar ${cmdLineJMXJar} ${user}:${password} ${jmxHost}:${port} com.company.data:type=datasystem,id=0

echo "Executing XML update..."
java -jar ${cmdLineJMXJar} - ${jmxHost}:${port} com.company.data:type=datasystem,id=0 jmxForceRefresh

jmxterm, здається, не працює на Java 7 bugs.launchpad.net/jmxterm/+bug/942693
artbristol

19

Я розробив jmxfuse, який розкриває JMX Mbeans як файлову систему Linux FUSE з аналогічною функціональністю, як / proc fs. Він спирається на Йолокію як міст до JMX. Атрибути та операції піддаються читанню та запису.

http://code.google.com/p/jmxfuse/

Наприклад, для читання атрибута:

me@oddjob:jmx$ cd log4j/root/attributes
me@oddjob:jmx$ cat priority

написати атрибут:

me@oddjob:jmx$ echo "WARN" > priority

викликати операцію:

me@oddjob:jmx$ cd Catalina/none/none/WebModule/localhost/helloworld/operations/addParameter
me@oddjob:jmx$ echo "myParam myValue" > invoke

12

Плагін Syabru Nagios JMX призначений для використання з Nagios, але не вимагає Nagios і дуже зручний для використання командного рядка:

~$ ./check_jmx -U service:jmx:rmi:///jndi/rmi://localhost:1099/JMXConnector --username myuser --password mypass -O java.lang:type=Memory -A HeapMemoryUsage -K used 
JMX OK - HeapMemoryUsage.used = 445012360 | 'HeapMemoryUsage used'=445012360;;;;

Це чудово, і дуже швидко. Близько 0,3 сек., Щоб повернути значення проти 3 секунд для jmxterm
sivann

9

Потенційно найпростіше написати це на Java

import javax.management.*;
import javax.management.remote.*;

public class JmxInvoke {

    public static void main(String... args) throws Exception {

        JMXConnectorFactory.connect(new JMXServiceURL(args[0]))
            .getMBeanServerConnection().invoke(new ObjectName(args[1]), args[2], new Object[]{}, new String[]{})


    }

}

Це складе один клас .clas та не потребує залежностей у сервері чи будь-якій складній упаковці Maven.

зателефонуйте йому

javac JmxInvoke.java
java -cp . JmxInvoke [url] [beanName] [method]

4

Трохи ризиковано, але ви можете запустити команду POST curl зі значеннями форми з консолі JMX, її URL-адресою та автентифікацією http (якщо потрібно):

curl -s -X POST --user 'myuser:mypass'
  --data "action=invokeOp&name=App:service=ThisServiceOp&methodIndex=3&arg0=value1&arg1=value1&submit=Invoke"
  http://yourhost.domain.com/jmx-console/HtmlAdaptor

Остерігайтеся: індекс методу може змінюватися зі змінами програмного забезпечення. І реалізація веб-форми може змінитися.

Вищенаведене базується на джерелі сторінки сервісу JMX для операції, яку потрібно виконати:

http://yourhost.domain.com/jmx-console/HtmlAdaptor?action=inspectMBean&name=YourJMXServiceName

Джерело форми:

form method="post" action="HtmlAdaptor">
   <input type="hidden" name="action" value="invokeOp">
   <input type="hidden" name="name" value="App:service=ThisServiceOp">
   <input type="hidden" name="methodIndex" value="3">
   <hr align='left' width='80'>
   <h4>void ThisOperation()</h4>
   <p>Operation exposed for management</p>
    <table cellspacing="2" cellpadding="2" border="1">
        <tr class="OperationHeader">
            <th>Param</th>
            <th>ParamType</th>
            <th>ParamValue</th>
            <th>ParamDescription</th>
        </tr>
        <tr>
            <td>p1</td>
           <td>java.lang.String</td>
         <td> 
            <input type="text" name="arg0">
         </td>
         <td>(no description)</td>
        </tr>
        <tr>
            <td>p2</td>
           <td>arg1Type</td>
         <td> 
            <input type="text" name="arg1">
         </td>
         <td>(no description)</td>
        </tr>
    </table>
    <input type="submit" value="Invoke">
</form>

Я реалізував це таким чином з Java за допомогою a HttpURLConnectionі можу підтвердити, що він працює. (btw. submit=Invokeнепотрібно)
tom

чи можна описати, як це працює? Я маю на увазі, за замовчуванням jmx використовує rmi, і там я бачу http. Чи означає це, що сервер має бути налаштований на підтримку jmx запитів http?
Психозой

3

Погляньте на JManage . Він може виконувати методи MBean та отримувати / встановлювати атрибути з командного рядка .


Єдиним недоліком є ​​використання утиліти командного рядка, вона вимагає запуску JManage для проксі-команд на ваших серверах JMX. Я вважаю за краще більш легкий підхід безпосередньо до самого сервера JMX.
Dougnukem

3

Можливо, ви також хочете подивитися на jmx4perl . Він забезпечує доступ без Java до MBeans віддаленого сервера Java EE Server. Однак невеликий сервлет агента повинен бути встановлений на цільовій платформі, що забезпечує спокійний доступ JMX через HTTP з корисним навантаженням JSON. (Версія 0.50 додасть режим без агента шляхом впровадження проксі-сервера JSR-160).

Переваги - це швидкий час запуску порівняно з запуском локального Java JVM та простота використання. jmx4perl постачається з повним набором модулів Perl, які можна легко використовувати у власних сценаріях:

use JMX::Jmx4Perl;
use JMX::Jmx4Perl::Alias;   # Import certains aliases for MBeans

print "Memory Used: ",
      JMX::Jmx4Perl
          ->new(url => "http://localhost:8080/j4p")
          ->get_attribute(MEMORY_HEAP_USED);

Ви також можете використовувати псевдоніми для звичайних комбінацій MBean / Attribute / Operation (наприклад, для більшості MXBeans). Для отримання додаткових функцій (Nagios-Plugin, XPath-подібний доступ до складних типів атрибутів, ...), будь ласка, зверніться до документації jmx4perl.


1

@Dougnukem відповідь мені дуже допомогла. Я взяв підхід Groovy (використовуючи groovy 2.3.3).

Я змінив код Dougnukem. Це буде працювати з Java 7 і друкуватиме два атрибути для stdout кожні 10 сек.

        package com.my.company.jmx
        import groovy.util.GroovyMBean;
        import javax.management.remote.JMXServiceURL
        import javax.management.remote.JMXConnectorFactory
        import java.lang.management.*

            class Monitor {
                static main(args) {
                    def serverUrl = 'service:jmx:rmi:///jndi/rmi://localhost:5019/jmxrmi'
                    String beanName = "Catalina:type=DataSource,class=javax.sql.DataSource,name=\"jdbc/CommonDB\""
                    println  "numIdle,numActive"

                    while(1){
                        def server = JMXConnectorFactory.connect(new JMXServiceURL(serverUrl))
                       //make sure to reconnect in case the jvm was restrated 
                        server.connect()
                        GroovyMBean mbean = new GroovyMBean(server.MBeanServerConnection, beanName)
                        println  "${mbean.numIdle},${mbean.numActive}"
                        server.close()
                        sleep(10000)
                    }

                }
            }

Скомпілюйте цей код у банку, використовуючи плагін maven-compiler, щоб вам не знадобилася groovy установка лише groovy-all.jar. Нижче наведено відповідне визначення та залежність плагіна.

   <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <compilerId>groovy-eclipse-compiler</compilerId>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-compiler</artifactId>
                        <version>2.8.0-01</version>
                    </dependency>
                    <dependency>
                        <groupId>org.codehaus.groovy</groupId>
                        <artifactId>groovy-eclipse-batch</artifactId>
                        <version>2.3.4-01</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.3</version>
        </dependency>
    </dependencies>

Оберніть її битою або оболонкою, і вона надрукує дані для stdout.


0

Я не впевнений у середовищі, що нагадує баш. Ви можете спробувати кілька простих програм для обгортки на Java (з аргументами програми), які викликають ваші MBeans на віддаленому сервері. Потім ви можете зателефонувати цим обгорткам із сценарію оболонки

Якщо ви можете використовувати щось на зразок Python або Perl, вас може зацікавити JSR-262, що дозволяє вам піддавати операції JMX над веб-службами. Планується, що це буде включено в Java 7, але ви, можливо, зможете скористатися кандидатом на випуск референтної реалізації

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.