JMX - Technologie pour le monitoring d'applications Java
Les composants d'un agent JMX
L'agent JMX (également appelé serveur JMX) se compose en trois parties :
- Le serveur de MBeans
- Les connecteurs et adaptateurs de protocoles
- Les services
Le serveur de MBeans (Objet MBeanServer)
Le serveur de MBeans est un objet de l'agent JMX. Il a pour objectif de centraliser toutes les ressources métiers devant être gérées par les applications de gestion clientes. Ce serveur est lié aux connecteurs et adaptateurs de protocoles (la relation entre ces deux entités est expliquée dans la section "Les connecteurs et adaptateurs de protocoles" de cette même page). La JVM possède par défaut un serveur de MBean. C'est sur le serveur de MBeans de la JVM de notre serveur JMX que nous allons la plupart du temps enregistrer nos ressources. L'instanciation du serveur de MBeans se fait comme ceci :
private final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
Il faut ensuite enregistrer les ressources avec la méthode registerMBean de l'objet MBeanServer. Reprenons l'exemple de la classe MaClasse de la page précédente à propos des MBeans. Nous allons donc utiliser cette méthode pour enregistrer notre ressource auprès de notre serveur de MBeans. Il est nécessaire d'utiliser la classe ObjectName qui donne un nom à notre MBean. Cela permet de classer nos MBeans dans l'arborescence de notre MBeanServer. Voici un exemple d'enregistrement de MaClasse dans notre serveur de MBean précédemment déclaré :
MaClasse maClasse = new MaClasse(36); mbs.registerMBean(maClasse, new ObjectName("fr.mon.package:type=MaClasse"));
Les connecteurs et adaptateurs de protocoles
L'agent JMX offre des outils permettant à des applications de gestion de se connecter au serveur de MBeans et ainsi de contrôler les ressources. Cela peut se faire par l'intermédiaire de deux entités : les connecteurs et les adaptateurs.
Les connecteurs
Les connecteurs permettent à une application cliente d'établir une liaison avec l'agent JMX. Celle-ci se fait dans un environnement Java. On utilise le protocole RMI (Remote Method Invocation) propre à Java pour se connecter au serveur JMX. L'objet permettant de faire ce lien côté client est l'objet JMXConnector. En ce qui concerne le serveur, il s'agit de l'objet JMXConnectorServer. Il faut attacher le serveur à un objet JMXServiceURL. Ces différents objets sont compris dans le package javax.management. Voici comment lier le serveur de MBean au connecteur :
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + PORT_CONNECTOR + "/server"); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, getAuthsConnector(), mbs); cs.start();
L'implémentation d'un client JMX via un connecteur rend le client dépendant de ce package et donc de l'API JMX. Cela n'est pas pratique lorsqu'on souhaite que le client ne soit pas en Java (reprise d'application de gestion SNMP, client sur un mobile Android qui par défaut n'inclut pas le package javax.management...). Pour réaliser ce type de client, il est nécessaire d'utiliser les adaptateurs de protocoles.
Les adaptateurs
Les adaptateurs sont des objets permettant de faire le lien entre un client et un serveur JMX sans être dépendant de Java côté client. Il est cependant nécessaire dans le cadre d'une utilisation des adaptateurs d'ajouter l'implémentation de référence JMX dans l'agent (jmxri.jar et jmxtools.jar).
Les services (Notification et Timer)
L'agent JMX permet de gérer un système de notification pour les ressources. L'API JMX propose pour cela deux classes dans le package javax.management appelées Notification et Timer. Ces classes doivent être implémentées dans nos ressources.
Les notifications (objet Notification)
Les notifications sont de simples alertes apériodiques. Elles servent aux clients s'étant préalablement abonnés d'être prévenus lors de la modification de la ressource. Cela permet d'alerter le changement de valeur d'un attribut par exemple. Voici un exemple de notification sur la méthode setValue de MaClasse :
@Override public void setValue(boolean value) { nbValueChanged++; Notification n = new AttributeChangeNotification(this, nbValueChanged, System.currentTimeMillis(), "Modification de l'attribut value", "boolean", this.value, value); sendNotification(n); this.value = value; }
Une fois que le client aura souscrit à cet abonnement (via la jConsole par exemple), il sera possible pour lui de recevoir une alerte à chaque fois que la valeur de "value" changera.
Les timers (objet Timer)
Les timers sont des notifications périodiques. Ils sont utiles si nous souhaitons être alertés à plusieurs reprises sur le dépassement d'un seuil maximum par exemple. Un exemple de timer est présenté dans la partie "Démonstration" de ce site.