Accéder au contenu principal

Intégrez JMX dans vos applications

JMX (Java Management eXtension)! Le seul nom peut faire peur et pourtant, cette technologie peut très facilement être intégrée dans vos applications Java de la plus simple à la plus complexe sans surcout particulier. Elle est en effet incluse dans Java SE depuis la version 1.5. Tout d'abord, à quoi cela peut t'il servir? Le premier usage de base est que JMX permet de surveiller les ressources utilisées par une application (mémoire, CPU, nombre de threads, système d'exploitation, etc). Ces informations sont fournies de base par la machine virtuelle. Vous pouvez cependant rajouter des informations spécifiques à votre application. L'API JMX vous permet de :
  • Exposer des propriétés de configuration qui pourront être consultées ou modifiées. 
  • Exposer des méthodes qui permettront de contrôler l'application pour l'arrêter, démarrer des modules, etc.
  • Afficher des notifications d'alarmes
Dans des systèmes en production, JMX peut être intégré à des systèmes de monitoring d'applications tels que Zabbix, Nagios pour n'en citer que quelques uns. Il peut également être utilisé avec JConsole qui est une application gratuite livrée avec le JDK depuis la version 1.5.

Exposer des attributs avec JMX

L'une des utilisations les plus simples de JMX consiste à exposer des propriétés de configuration. Il faut pour cela déclarer une interface et son implémentation. Il n'y a qu'une seule contrainte de nommage de l'interface. Si le nom de la classe est Test, l'interface correspondante doit s'appeler TestMBean. Le MBean ajouté en fin de classe permet ainsi d'indiquer les attributs et méthodes qui seront exposés, la classe d'implémentation peut contenir d'autres classes publiques qui ne seront pas exposées.
Voici un premier exemple avec une classe de configuration de base de données. Je vais donc appeler l'interface DatabaseManagementMBean.

 package com.jmxtest.mbeans;  
   
 public interface DatabaseManagementMBean {  
      String getDbUser();  
      void setDbUser(String user);  
      String getDbPassword();  
      void setDbPassword(String password);  
      String getDbDriver();  
      void setDbDriver(String dbDriver);  
      String getDbURL();  
      void setDbURL(String dbURL);  
      Long getDbCounter();  
 }  
Notez que la dernière méthode getDbCounter n'a pas de méthode set correspondante ce qui signifie que l'attribut "dbCounter" est en lecture seule. Cela n'empêche pas d'implémenter une méthode setDbCounter dans l'implémentation. Cette dernière ne sera simplement pas visible.

L'implémentation de l'interface doit donc s'appeler DatabaseManagement (sans le MBean).

 package com.jmxtest.mbeans;  
   
 public class DatabaseManagement implements DatabaseManagementMBean {  
      String dbDriver = "org.apache.derby.jdbc.ClientDriver";  
      String dbURL = "jdbc:derby://localhost:1527/testjmx";  
      String dbUser = "linus";  
      String dbPassword = "ChangeMe";  
      Integer dbCounter = 0;  
        
      public DatabaseManagement() {  
      }  
   
      public String getDbDriver() {  
           return dbDriver;  
      }  
   
      public String getDbPassword() {  
           return dbPassword;  
      }  
   
      public String getDbURL() {  
           return dbURL;  
      }  
   
      public String getDbUser() {  
           return dbUser;  
      }  
   
      public void setDbDriver(String dbDriver) {  
           this.dbDriver = dbDriver;  
      }  
   
      public void setDbPassword(String dbPassword) {  
           this.dbPassword = dbPassword;  
      }  
   
      public void setDbURL(String dbURL) {  
           this.dbURL = dbURL;  
      }  
   
      public void setDbUser(String dbUser) {  
           this.dbUser = dbUser;  
      }  
   
      public Integer getDbCounter() {  
           return dbCounter;  
      }  
   
      public void setDbCounter(Integer dbCounter) {  
           this.dbCounter = dbCounter;  
      }  
 }  
   


L'exposition de la classe pour JMX se fait de la manière suivante.
 import java.lang.management.ManagementFactory;  
   
 import javax.management.MBeanServer;  
 import javax.management.ObjectName;  
   
 import com.jmxtest.mbeans.DatabaseManagement;  
   
 public class TestJMXProperties {  
      // MBeans  
      DatabaseManagement databaseConfig;  
        
      public TestJMXProperties() {  
           createMBeans();            
      }  
   
      //Register MBeans  
      private void createMBeans() {  
           try {  
                System.out.println("Creating MBeans");  
                MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();   
   
                databaseConfig = new DatabaseManagement();  
                ObjectName databaseName = new ObjectName("TestJMX:name=Database Management");  
                mbs.registerMBean(databaseConfig, databaseName);  
           } catch (Exception e) {  
                System.out.println(e.getMessage());  
                e.printStackTrace();  
           }  
      }  
   
      // Initialize the mbeans  
        
      public static void main(String[] args) throws InterruptedException {  
           TestJMXProperties test = new TestJMXProperties();  
           Integer counter = 0;  
           while (true) {                 
                Thread.sleep(10000);                 
                System.out.println("Waiting 10 seconds " + counter);  
                test.databaseConfig.setDbCounter(counter++);  
           }  
      }  
 }  
   

Exécutez l'application avec les options suivantes :
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=1333

Les nouvelles propriétés peuvent être visualisées avec l'application JConsole. Sélectionnez l'application à superviser.


Avec Java 1.7, la sécurité a été renforcée. JConsole essaye d'abord de se connecter en mode SSL sécurisé. En ayant démarré avec les options indiquées précédemment, vous pouvez vous connecter en mode "Insecure connection".


Après la connexion, allez sur l'onglet MBean puis l'objet TestJMX. Vous verrez la liste des attributs définis dans l'application.


L'attribut dbCounter est en lecture seule. En double-cliquant sur la valeur, elle apparaitra sous forme de graphe qui peut ainsi être sauvegardé.


Vous pouvez également utiliser l'application JVisualVM après avoir rajouté le plugin VisualVM-MBeans.


L'affichage est similaire à JConsole et vous pouvez également profiler votre application.

Exposez des méthodes

Le principe d'exposition des opérations est le même que celui des propriétés. La méthode Java ne doit simplement pas commencer par "set" ou "get" pour être considérée comme une opération.
Je vais maintenant définir une classe MainManagement avec son interface MainManagementMBean. Encore une fois, seul le nommage MBean permet d'indiquer qu'il s'agit de l'interface qui expose les méthodes.

L'interface MainManagementMBean contient les méthodes suivantes.

 package com.jmxtest.mbeans;  
   
 public interface MainManagementMBean {  
      public void stop();  
      public void reload();  
      public void debug(boolean on);  
      public void save();  
 }  
   


Je défini ici une implémentation de cette interface juste à titre d'exemple.

 package com.jmxtest.mbeans;
   
 // Main Management class  
   
 public class MainManagement implements MainManagementMBean {  
        
      public static volatile MainManagement _instance = null;  
   
      boolean debug = false;  
        
      // MBeans  
      DatabaseManagement databaseConfig;     // Database MBean  
      MainManagement main;     // Ini file content and operations  
        
        
      // Constructor that loads the ini file  
      public MainManagement(){  
           loadIniFile();  
      }  
   
      // Retrieves a unique instance of the class  
        
      public static MainManagement getInstance() {  
           if (_instance == null)  
                _instance = new MainManagement();  
           return _instance;  
      }       
   
      // Private method to load the configuration file  
        
      private void loadIniFile() {  
           System.out.println("Load configuration file");  
           databaseConfig = new DatabaseManagement();  
           debug = false;  
      }  
        
      // Private method to save the configuration file  
        
      private void saveIniFile() {  
           System.out.println("Saving ini file");            
      }  
        
      // Turns the application in debug mode.  
      // This has to be completed according to the debug framework used  
   
      public void debug(boolean on) {  
           System.out.println("Debug=" + on);  
           debug = on;  
      }  
   
      // Reloads the ini file  
        
      public void reload() {  
           loadIniFile();  
      }  
   
      // Exposed method to save the configuration file  
        
      public void save() {  
           saveIniFile();  
      }  
   
      // Exposed method to stop the application.  
      // Security must be put in place when this kind of methods are publicly exposed,   
        
      public void stop() {  
           System.out.println("Stop");  
           System.exit(0);  
      }  
        
      public DatabaseManagement getDatabaseConfig() {  
           return databaseConfig;  
      }
 }

L'enregistrement du MBean se fait de la même manière que précédemment.

 import java.lang.management.ManagementFactory;  
 import java.text.SimpleDateFormat;  
 import java.util.Calendar;  
   
 import javax.management.MBeanServer;  
 import javax.management.ObjectName;  
   
 import com.jmxtest.mbeans.MainManagement;  
 import com.jmxtest.mbeans.DatabaseManagement;  
   
 public class TestJMX {  
   
      // MBeans  
      DatabaseManagement databaseConfig;  
      MainManagement main;  
        
      public TestJMX() {  
           createMBeans();            
      }  
   
      //Register MBeans  
      private void createMBeans() {  
           try {  
                System.out.println("Creating MBeans");  
                MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();   
   
                main = MainManagement.getInstance();  
                ObjectName mainName = new ObjectName("TestJMX:name=TestJMX Management");  
                mbs.registerMBean(main, mainName);  
                  
                databaseConfig = main.getDatabaseConfig();  
                ObjectName databaseName = new ObjectName("TestJMX:name=Database Management");  
                mbs.registerMBean(databaseConfig, databaseName);  
           } catch (Exception e) {  
                System.out.println(e.getMessage());  
                e.printStackTrace();  
           }  
      }  
   
      // Initialize the mbeans  
        
      public static void main(String[] args) throws InterruptedException {  
           TestJMX testJMX = new TestJMX();  
           Integer counter = 0;  
           while (true) {  
                Thread.sleep(10000);  
                System.out.println("Waiting 10 seconds");  
                testJMX.databaseConfig.setDbCounter(counter++);  
           }  
      }  
 }  
   

Les méthodes ainsi exposées sont maintenant visibles dans JConsole et peuvent être appelées.


Voici donc comment avec quelques classes Java tout à fait standard et sans librairie additionnelle il est possible d'offrir une interface permettant de contrôler votre application à distance.

Commentaires

Posts les plus consultés de ce blog

Utilisez votre tablette Android comme second écran pour Linux (Raspberry Pi, MK908II)

Les tablettes Android atteignent désormais des prix qui défient toute concurrence. On trouve désormais des modèles à 39 € TTC en super marché, soit à peine plus cher que le Raspberry PI, mais avec un écran. Ces modèles souvent mono-core 1Ghz ou 1,4 Ghz avec 512 ou 1Go de mémoire ne sont très probablement pas utilisables pour une utilisation régulière sur Internet et ne sont en aucun point comparables à leur équivalent de marque (Samsung, Sony, LG, HTC, Lenovo, etc). Plusieurs tutoriels indiquent comment connecter utiliser une tablette Android comme second écran ( http://www.linux-magazine.com/Online/Blogs/Productivity-Sauce/Use-an-Android-Device-as-Screen-and-Input-for-Raspberry-Pi ). Ces méthodes utilisent généralement l'USB Tethering qui n'est malheureusement disponible que sur les téléphones ou tablettes avec un accès mobile (3G ou 4G) inclus. Dans ce billet, je vais vous montrer comment se connecter à une tablette en utilisant le mode Debug adb (Android Debug Bridge

Supprimer les partitions Raspberry sur une carte SD sous Windows avec Diskpart

Si vous souhaitez récupérer une ancienne carte SD utilisée pour démarrer un Raspberry pour un autre usage (appareil photo, etc), il vous faudra supprimer les deux partitions créées au moment de l'écriture de l'image sur la carte SD. Vous pouvez voir les partition en sélectionnant Menu Windows/Ordinateur/bouton droit "Gérer". Voici un exemple du résultat final. Vous pouvez supprimer la partition Unix de 7 Gb (ou 4Gb en fonction de la taille de votre carte) en sélectionnant la partition puis en faisant "bouton droit Supprimer". Laissez juste une partition pour pouvoir faire les autres manipulations avec DISKPART. Démarrez l'outil DISKPART en ligne de commande. Une nouvelle fenêtre s'ouvrira. Microsoft DiskPart version 6.1.7601 Copyright (C) 1999-2008 Microsoft Corporation. DISKPART> list disk   N° disque  Statut         Taille   Libre    Dyn  GPT   ---------  -------------  -------  -------  ---  ---   Disque 0    En ligne        238 G octe

Emulateur Raspberry Pi sous Windows

Si vous souhaitez développer ou tester des applications pour Raspberry Pi, vous pouvez, soit compiler directement l'application sur Raspberry, soit la développer sous Linux ou Windows et la compiler pour Raspberry. La seconde solution est souvent plus simple car elle permet de disposer d'un environnement de compilation complet tel qu'Eclipse pour le développement. Une fois l'application développée, il faut la tester sur Raspberry. Là, il faut copier l'application en utilisant un client FTP ou SCP, puis se connecter en SSH et lancer l'exécutable. Il existe un autre moyen de tester une application Raspberry sans avoir à l'allumer. Il suffit de passer par un émulateur tel que QEMU qui permet de lancer un OS pour processeur ARM sous Linux ou Windows. L'émulateur sous Windows 1. Récupérez l'émulateur à l'adresse suivante : http://sourceforge.net/projects/rpi-emulator-win32/ . 2. Dézippés le contenu de l'image Rpi-Occidentalis-v02-qemu.7z av