Existe-t-il des bibliothèques qui me permettraient d’appeler une méthode JMX MBean à partir d’un script Shell? Nous exposons certaines commandes opérations/admin via JMX et nos administrateurs peuvent utiliser JConsole ou VisualVM, mais il est préférable de laisser certaines tâches à l’automatisation. Dans cette automatisation, nous aimerions pouvoir appeler une méthode JMX MBean sur notre serveur en cours d'exécution, de préférence à partir d'un script Shell.
Les utilitaires JMX en ligne de commande suivants sont disponibles:
Exemple de 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();
Exemple avec cmdline-jmxclient:
Si vous avez un
Avec une opération appelée:
Ensuite, vous pouvez écrire un script bash simple (en supposant que vous téléchargiez --- (cmdline-jmxclient-0.10.3.jar et placez-le dans le même répertoire que votre 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
J'ai développé jmxfuse qui expose JMX Mbeans en tant que système de fichiers Linux Fuse avec des fonctionnalités similaires à celles du fichier/proc. Il s'appuie sur Jolokia comme pont vers JMX. Les attributs et les opérations sont exposés en lecture et en écriture.
http://code.google.com/p/jmxfuse/
Par exemple, pour lire un attribut:
me@oddjob:jmx$ cd log4j/root/attributes
me@oddjob:jmx$ cat priority
écrire un attribut:
me@oddjob:jmx$ echo "WARN" > priority
invoquer une opération:
me@oddjob:jmx$ cd Catalina/none/none/WebModule/localhost/helloworld/operations/addParameter
me@oddjob:jmx$ echo "myParam myValue" > invoke
Le plugin Syabru Nagios JMX est destiné à être utilisé depuis Nagios, mais ne nécessite pas Nagios et est très pratique pour une utilisation en ligne de commande:
~$ ./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;;;;
C'est potentiellement le plus facile à écrire en 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[]{})
}
}
Cela compilerait dans une seule classe .class et ne nécessiterait aucune dépendance du serveur ni aucun empaquetage maven compliqué.
appelle avec
javac JmsInvoke.Java
java -cp . JmxInvoke [url] [beanName] [method]
Un peu risqué, mais vous pourriez exécuter une commande curl POST) avec les valeurs du formulaire de la console JMX, son authentification URL et http (si nécessaire):
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
Attention: l'index de méthode peut changer avec les modifications du logiciel. Et la mise en œuvre du formulaire Web pourrait changer.
Ce qui précède est basé sur le source de la page de service JMX pour l’opération que vous souhaitez effectuer:
http://yourhost.domain.com/jmx-console/HtmlAdaptor?action=inspectMBean&name=YourJMXServiceName
Source de la forme:
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>
Vous voudrez peut-être aussi jeter un oeil à jmx4Perl . Il fournit un accès sans Java à un MBean distant Java EE Server. Cependant, un petit servlet d'agent doit être installé sur la plate-forme cible, ce qui permet un accès reposant à JMX via HTTP avec une charge JSON . (La version 0.50 ajoutera un mode sans agent en implémentant un proxy JSR-160).
Les avantages sont des temps de démarrage rapides comparés au lancement d'une JVM locale Java et facilité d'utilisation). Jmx4Perl est livré avec un ensemble complet de modules Perl qui peuvent facilement être utilisés dans vos propres scripts:
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);
Vous pouvez également utiliser un alias pour les combos MBean/Attribut/Opération courants (par exemple, pour la plupart des MXBeans). Pour des fonctionnalités supplémentaires (Nagios-Plugin, accès XPath à des types d'attributs complexes, ...), veuillez vous reporter à la documentation de jmx4Perl.
Jetez un oeil à JManage . Il est capable d'exécuter des méthodes MBean et d'obtenir/définir des attributs à partir de ligne de commande .
@Dougnukem answer m'a beaucoup aidé. J'ai adopté l'approche Groovy (en utilisant groovy 2.3.3).
J'ai fait quelques changements sur le code Dougnukem. Cela fonctionnera avec Java 7 et imprimera deux attributs sur la sortie standard toutes les 10 secondes.
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)
}
}
}
Compilez ce code dans un fichier jar à l'aide de maven-compiler-plugin afin de ne pas nécessiter une installation groovy uniquement du fichier groovy-all.jar. Vous trouverez ci-dessous la définition et la dépendance du plugin.
<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>
Enveloppez-le avec une batte ou un shell et il imprimera les données sur la sortie standard.
Je ne suis pas sûr de l'environnement bash-like. Vous pouvez essayer quelques programmes d'encapsulation simples dans Java (avec les arguments du programme) qui appellent vos MBeans sur le serveur distant. Vous pouvez ensuite appeler ces wrappers à partir du script Shell.
Si vous pouvez utiliser quelque chose comme Python ou Perl, cela pourrait vous intéresser JSR-262 , ce qui vous permet d'exposer les opérations JMX sur des services Web. inclus dans Java 7 mais vous pourrez peut-être utiliser une version candidate de implémentation de référence