JMX est un framework de gestion de la technologie qui permet de surveiller et de gérer des applications Java à distance.
On définit des beans de gestion appelés *MBeans (pour Management Bean) qui donnent accès à :
beans
Management Bean
Ensuite, par l’intermédiaire d’un client JMX, on accéde à ces informations et fonctionnalités à distance. Cela permet de surveiller et de gérer votre application de manière centralisée.
client JMX
Vous pouvez donner accès aux informations suivantes :
JMX peut être particulièrement utile dans les environnements de production pour surveiller et diagnostiquer les problèmes de performance et de stabilité.
Il faut créer un serveur JMX pour donner accès à vos MBeans via un serveur RMI (Remote Method Invocation). Il suffit ensuite d’utiliser un client JMX pour y accèder à distance via RMI.
Voici ci-dessous un exemple d’implémentation de JMX avec SpringBoot :
Exemple de code :
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jmx.support.ConnectorServerFactoryBean; import org.springframework.remoting.rmi.RmiRegistryFactoryBean; @Configuration public class JmxConfiguration { @Bean public RmiRegistryFactoryBean rmiRegistry() { final RmiRegistryFactoryBean rmiRegistryFactoryBean = new RmiRegistryFactoryBean(); rmiRegistryFactoryBean.setPort(1099); // port d'écoute return rmiRegistryFactoryBean; } @Bean public ConnectorServerFactoryBean connectorServerFactoryBean() throws Exception { final ConnectorServerFactoryBean connectorServerFactoryBean = new ConnectorServerFactoryBean(); connectorServerFactoryBean.setObjectName("connector:name=rmi"); connectorServerFactoryBean.setServiceUrl("service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxrmi"); return connectorServerFactoryBean; } }
Pour exposer vos MBeans avec Spring Boot, vous pouvez utiliser l’annotation @ManagedResource sur vos beans de gestion. Ce bean ci-dessous sera alors publié sur votre serveur JMX et vous pourrez accéder à ses informations et fonctionnalités à distance.
@ManagedResource
En fait, on associe plusieurs technologies pour arriver à ce résultat.
import org.springframework.jmx.export.annotation.ManagedResource; @ManagedResource public class MyService { // ... }
Le code ci-dessous permet de se connecter à notre serveur JMX sur l’URL spécifiée et imprime la liste des MBeans publiés sur le serveur. Pour commencer, c’est pratique !
Vous pouvez ensuite utiliser les méthodes de l’interface MBeanServerConnection pour accéder aux informations et aux fonctionnalités des MBeans.
MBeanServerConnection
Utilisez :
import java.io.IOException; import java.util.Set; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class JmxClient { public static void main(String[] args) throws IOException { // Créez une URL de service JMX pour vous connecter au serveur JMX JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi"); // Créez un connecteur JMX et connectez-vous au serveur JMXConnector jmxConnector = JMXConnectorFactory.connect(url); MBeanServerConnection connection = jmxConnector.getMBeanServerConnection(); // Obtenez la liste des MBeans publiés sur le serveur Set<ObjectName> mbeans = connection.queryNames(null, null); for (ObjectName mbean : mbeans) { System.out.println(mbean); } // Fermez le connecteur jmxConnector.close(); } }
Vous avez de la chance car Spring Boot expose automatiquement certaines informations de configuration et de la jvm via JMX.
Pour accéder aux informations de configuration de votre application Spring Boot via JMX, vous pouvez utiliser l’MBean org.springframework.boot:type=Admin,name=SpringApplication. Ce MBean expose les propriétés de configuration de votre application sous forme d’attributs.
org.springframework.boot:type=Admin,name=SpringApplication
Par exemple, vous pouvez utiliser getAttribute(objectName, “spring.application.name”) pour lire le nom de votre application.
Exemple de code pour lire les propriétés de configuration de votre application SpringBoot avec un client JMX :
import javax.management.MBeanServerConnection; import javax.management.ObjectName; public class ConfigurationPrinter { public static void printConfiguration(MBeanServerConnection connection) throws Exception { ObjectName objectName = new ObjectName("org.springframework.boot:type=Admin,name=SpringApplication"); String[] propertyNames = (String[]) connection.getAttribute(objectName, "propertyNames"); for (String propertyName : propertyNames) { Object propertyValue = connection.getAttribute(objectName, propertyName); System.out.println(propertyName + " = " + propertyValue); } } }
Autre exemple :
Accédez aux informations de jvm de votre application en utilisant le MBean java.lang:type=Memory. Ce dernier donne des informations sur l’utilisation de la mémoire de votre jvm sous forme d’attributs.
Par exemple, vous pouvez utiliser cette écriture pour y accéder : getAttribute(objectName, “HeapMemoryUsage”). Vous obtenez alors l’utilisation de la mémoire heap de votre jvm.
Exemple de code pour lire les informations de jvm :
import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.openmbean.CompositeData; public class JvmInfoPrinter { public static void printJvmInfo(MBeanServerConnection connection) throws Exception { ObjectName objectName = new ObjectName("java.lang:type=Memory"); CompositeData heapMemoryUsage = (CompositeData) connection.getAttribute(objectName, "HeapMemoryUsage"); long used = (long) heapMemoryUsage.get("used"); long max = (long) heapMemoryUsage.get("max"); System.out.println("Heap memory usage: " + used + " / " + max); } }
Ce n’est pas si compliquer, il faut juste lire la documentation et savoir ce que vous voulez rendre accessible comme informations. Je me souviens que les informations du serveur J2EE JBoss permettait l’accès à de nombreux MBeans car au serveur JMX intégré.
De toute façon, avec Spring ou SpringBoot ça devient plus simple !