Chiamare il metodo MBean JMX da uno script di shell

Ci sono librerie che mi permettono di chiamare un metodo MBean JMX da uno script di shell. Esaminiamo alcune operazioni / comandi di amministrazione tramite JMX e potremmo fare in modo che i nostri amministratori utilizzino JConsole o VisualVM, ma alcune attività sono meglio lasciate all’automazione. In tale automazione vorremmo essere in grado di chiamare un metodo MBean JMX sul nostro server in esecuzione, preferibilmente da uno script di shell.

    Sono disponibili le seguenti utility della riga di comando JMX:

    1. jmxterm : sembra essere l’utilità più completa.
    2. cmdline-jmxclient – usato nel progetto WebArchive sembra molto semplice (e nessuno sviluppo dal 2006 sembra)
    3. Script Groovy e JMX – fornisce alcune funzionalità JMX davvero potenti ma richiede l’installazione di groovy e altre librerie.
    4. Funzionalità della riga di comando JManage : (il lato negativo è che richiede un server JManage in esecuzione per eseguire i comandi proxy tramite)

    Groovy JMX Esempio:

    import java.lang.management.* import javax.management.ObjectName import javax.management.remote.JMXConnectorFactory as JmxFactory import javax.management.remote.JMXServiceURL as JmxUrl import groovy.swing.SwingBuilder import javax.swing.WindowConstants as WC 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(); 

    esempio cmdline-jmxclient:

    Se hai un

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

    Con un’operazione chiamata:

    • jmxForceRefresh ()

    Quindi puoi scrivere un semplice script bash (assumendo che tu scarichi cmdline-jmxclient-0.10.3.jar e inserisca la stessa directory del tuo script):

     #!/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 

    Ho sviluppato jmxfuse che espone JMX Mbeans come un filesystem Linux FUSE con funzionalità simili a / proc fs. Si basa su Jolokia come ponte per JMX. Gli attributi e le operazioni sono esposti per la lettura e la scrittura.

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

    Ad esempio, per leggere un attributo:

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

    scrivere un attributo:

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

    per richiamare un’operazione:

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

    Il plugin Syabru Nagios JMX è pensato per essere utilizzato da Nagios, ma non richiede Nagios ed è molto conveniente per l’uso da riga di comando:

     ~$ ./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;;;; 

    Un po ‘rischioso, ma potresti eseguire un comando POST con i valori del form dalla console JMX, il suo URL e l’autenticazione http (se necessario):

     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 

    Attenzione: l’indice del metodo può cambiare con le modifiche al software. E l’implementazione del modulo web potrebbe cambiare.

    Quanto sopra si basa sull’origine della pagina del servizio JMX per l’operazione che si desidera eseguire:

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

    Fonte del modulo:

     form method="post" action="HtmlAdaptor">    

    void ThisOperation()

    Operation exposed for management

    Param ParamType ParamValue ParamDescription
    p1 java.lang.String (no description)
    p2 arg1Type (no description)

    Dai un’occhiata a JManage . È in grado di eseguire metodi MBean e ottenere / impostare attributi dalla riga di comando .

    Potresti anche dare un’occhiata a jmx4perl . Fornisce accesso java-less agli MBean di Java EE Server remoto. Tuttavia, è necessario installare un piccolo servlet agent sulla piattaforma di destinazione, che fornisce un accesso JMX restful via HTTP con un payload JSON. (La versione 0.50 aggiungerà una modalità senza agente implementando un proxy JSR-160).

    I vantaggi sono tempi di avvio rapidi rispetto all’avvio di una JVM java locale e facilità d’uso. jmx4perl viene fornito con un set completo di moduli Perl che possono essere facilmente utilizzati nei propri script:

     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); 

    Puoi anche usare l’alias per le combinazioni comuni di MBean / Attribute / Operation (ad es. Per la maggior parte degli MXBeans). Per ulteriori funzionalità (Nagios-Plugin, accesso simile a XPath a tipi di attributi complessi, …), fare riferimento alla documentazione di jmx4perl.

    Potenzialmente è più facile scrivere questo in 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[]{}) } } 

    Questo dovrebbe essere compilato in una class .class e non richiede alcuna dipendenza dal server o da alcun complicato packaging di Maven.

    chiamalo con

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

    @Dougnukem risposta mi ha aiutato molto. Ho preso l’approccio Groovy (citando groovy 2.3.3)

    Ho apportato alcune modifiche al codice di Dougnukem. Questo funzionerà con java 7 e stamperà due attributi su stdout evet 10 sec.

      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) } } } 

    Compilare questo codice in un jar usando maven-compiler-plugin in modo da non richiedere l’installazione groovy solo groovy-all.jar Di seguito è riportata la definizione e la dipendenza del plugin pertinente.

         org.apache.maven.plugins maven-compiler-plugin  groovy-eclipse-compiler 1.7 1.7    org.codehaus.groovy groovy-eclipse-compiler 2.8.0-01   org.codehaus.groovy groovy-eclipse-batch 2.3.4-01        org.codehaus.groovy groovy-all 2.4.3   

    Avvolgilo con un pipistrello o una shell e stamperà i dati sullo stdout.

    Non sono sicuro dell’ambiente bash. Potresti provare alcuni semplici programmi wrapper in Java (con argomenti del programma) che invocano i tuoi MBean sul server remoto. È quindi ansible chiamare questi wrapper dallo script della shell

    Se puoi usare qualcosa come Python o Perl, potresti essere interessato a JSR-262 che ti permette di esporre le operazioni JMX sui servizi web. È previsto che sia incluso in Java 7, ma potresti essere in grado di utilizzare un candidato alla release dell’implementazione di riferimento