10 mar 2010

Mise en place de JMX avec Spring

Catégorie : Non classéJohnny Beuve @ 22 h 25 min

JMX (Java Management eXtension) permet de superviser et d’administrer les ressources logiciels s’exécutant sur une JVM locale ou distante. Cette approche permet donc d’inspecter l’état d’une application en production, de modifier son comportement, de notifier des évènements sans avoir une interruption de service.

La plupart des serveurs d’applications java incluent JMX. (JBoss, Websphère, Weblogic).

Cet article décrit rapidement JMX et propose un exemple très simple avec et sans le framework Spring.

JMX est composé de trois couches :

  • La couche instrumentation définit les ressources qui vont être monitorées. Ces ressources sont des MBeans qui ressemblent à de simples POJOs.
  • La couche agent qui permet le déploiement des MBeans, les notifications et le monitoring. Toutes communications avec les ressources monitorées passent donc par cette couche. Le composant principal de cette couche est le MBeanServeur qui enregistre notamment les MBeans.
  • La couche Remote Management gère les communications externes avec les agents au travers des adapteurs et des connecteurs. Les adapteurs permettent à un client de communiquer avec un MBeanServeur selon un protocole donné.

Quelles sont les étapes pour enregistrer un MBean

  • Il faut créer une interface dont le nom finit par MBean. Par exemple InstrumentMBean
  • Implémenter cette interface dans une classe dont le nom est celui de l’interface mais sans MBean à la fin. Par exemple Instrument. Attention la classe implémentant l’interface du MBean doit se trouver dans le même package, et avoir un constructeur sans paramètre.
  • Ensuite il suffit d’enregistrer cet MBean dans un MBeanServeur.

    • Instancier le MBean
    • Obtenir une référence de MBeanServer
    • Construire un ObjectName (Un ObjectName est composé de deux parties, le domaine et une paire (nom,valeur) séparée par des : , cela donne :  mon.domaine:type=MonMBeanAMoi)
    • Enregistrer le Mbean dans le MBeanServer en utilisant l’ObjectName unique que vous avez créé.

Votre MBean est enregistré, vous pouvez maintenant le consulter en utilisant la jconsole.

Faisons un exemple :

Interface :


package tuto.jmx;

public interface InstrumentMBean {
	public boolean isRunning();
	public void setRunning(boolean running);
	public void start();
	public void stop();
}


Implémentation :


package tuto.jmx;

public class Instrument implements InstrumentMBean {
	boolean running = false;

	@Override
	public boolean isRunning() {
		return running;
	}

	@Override
	public void setRunning(boolean running) {
		this.running = running;
	}

	@Override
	public void start() {
		running = true;
	}

	@Override
	public void stop() {
		running = false;
	}
}


Agent :


package tuto.jmx;

import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;

public class AgentMain {
	public static void main(String[] args) {
		Instrument instrument = new Instrument();
		MBeanServer ms = ManagementFactory.getPlatformMBeanServer();

		try {
			ObjectName oa = new ObjectName("mon.domaine:type=MonInstrument");
			ms.registerMBean(instrument, oa);
			System.out.println("Agent Running...");
			Thread.sleep(60000l);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Lancer le main et lancer simplement la jconsole (attention si vous utilisez java5, il faut lancer le main avec les paramètres suivants pour pouvoir se connecter en remote avec la jconsole « -Dcom.sun.management.jmxremote »)

On se connecte :



Connexion JConsole

on regarde les mbeans :



InstrumentMBean

Comment faire avec Spring :

  • Il faut juste créer un MBean. Par exemple ObservationBean
  • Il faut déclarer cet MBean dans le document de configuration de Spring

Voilà c’est suffisant vous pouvez maintenant lancer votre application Spring et consulter via la JConsole le MBean

Faisons un exemple :

Création du MBean :


package org.jo.dto;

import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;

/**
 * MBean dispayed in JMX console.
 */
@ManagedResource
public class ObservationBean {
	private Integer nbrEvent = 0;
	private Integer nbrBoundaryEvent = 10;

	public ObservationBean() {
		super();
	}

	public ObservationBean(Integer nbrEvent, Integer nbrBoundaryEvent) {
		super();
		setNbrBoundaryEvent(nbrBoundaryEvent);
		setNbrEvent(nbrEvent);
	}

	@ManagedAttribute
	public Integer getNbrEvent() {
		return nbrEvent;
	}

	public void setNbrEvent(Integer nbrEvent) {
		this.nbrEvent = nbrEvent;
	}

	@ManagedAttribute
	public Integer getNbrBoundaryEvent() {
		return nbrBoundaryEvent;
	}

	@ManagedAttribute
	public void setNbrBoundaryEvent(Integer nbrBoundaryEvent) {
		this.nbrBoundaryEvent = nbrBoundaryEvent;
	}

	@ManagedAttribute
	public boolean isOk() {
		return nbrEvent < nbrBoundaryEvent;
	}

	@Override
	public String toString() {
		return "System is " + (isOk()? "OK ": "HS ") + "(" + getNbrEvent()
				+ " event(s) for a limit of " + getNbrBoundaryEvent() + ")";
	}
}

@ManagedResource : cette annotation déclare le Bean comme MBean.
@ManagedAttribute : spécifie les attributs accessibles par les clients JMX.

Le document de configuration Spring est très simple :


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config />
	<context:mbean-export />

	<bean class="org.jo.jmx.ObservationEntry">
		<constructor-arg ref="observation" />
	</bean>

	<!-- Observation under jmx -->
	<bean id="observation" class="org.jo.dto.ObservationBean">
	</bean>

</beans>

Pour activer les annotations :

<context:annotation-config />


Pour exporter les MBeans Standards et des @ManagedResource

<context:mbean-export />

Conclusion

JMX est facile à mettre en place (encore plus facile avec Spring). Le champ d’application est large. On peut imaginer par exemple un MBean qui permet de faire fonctionner votre application en mode dégradé. Un autre MBean qui donne la possibilité de recharger les propriétés de votre application. Un MBean qui vous donne une vue générale de l’état des ressources dont a besoin votre application pour fonctionner normalement. Les administrateurs des serveurs d’applications seront enchantés.

Download

Vous trouverez ici un projet qui reprend les exemples de cet article. C’est un projet Maven2.

Mots-clefs : , ,