Mesurer la performance d’une classe Java avec JMeter

JMeter est un outil formidable permettant de réaliser des tests de performances d’applications et de serveurs selon différents protocoles ainsi que des tests fonctionnels[….].

Dans ce petit tutorial, je vais rapidement essayer de montrer comment réaliser des tests de performances sur une classe Java. Cette dernière sera plutôt simple, car elle ne réalise que des insertions dans une base de données MySQL via Hibernate.

Définissons dans un premier temps notre classe entité :

package fr.jahroots.xperiments.jmeter.entity;

public class Student implements java.io.Serializable {

	private static final long serialVersionUID = 1L;
	private Integer id;
	private String studentname;

	public Student() {
	}

	public Student(String studentname) {
		this.studentname = studentname;
	}

	// .... getters & setters

}

Le fichier mapping de la classe Student:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="fr.jahroots.xperiments.jmeter.entity.Student" table="student" catalog="test">
		<id name="id" type="java.lang.Integer">
			<column name="id" />
			<generator class="identity" />
		</id>
		<property name="studentname" type="string">
			<column name="studentname" length="60" not-null="true" />
		</property>
	</class>
</hibernate-mapping>

Le fichier de configuration d’Hibernate:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">xxxxxx</property>
		<property name="hibernate.connection.autocommit">true</property>
		<property name="hibernate.hbm2ddl.auto">create</property>
		<mapping resource="fr/jahroots/xperiments/jmeter/entity/Student.hbm.xml" />
	</session-factory>
</hibernate-configuration>

Il nous faut maintenant une classe qui sera chargée de charger notre configuration Hibernate, communément appelé HibernateUtil:

package fr.jahroots.xperiments.jmeter.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	 private static final SessionFactory sessionFactory;

	    static {
	        try {
	        		sessionFactory = new Configuration().configure().buildSessionFactory();
	        } catch (Throwable ex) {
	            System.err.println("Initial SessionFactory creation failed." + ex);
	            throw new ExceptionInInitializerError(ex);
	        }
	    }

	    public static SessionFactory getSessionFactory() {
	        return sessionFactory;
	    }
}

Nous disposons maintenant de tout ce dont on a besoin pour créer notre classe de test:

package fr.jahroots.xperiments.jmeter;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.threads.JMeterVariables;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import fr.jahroots.xperiments.jmeter.entity.Student;
import fr.jahroots.xperiments.jmeter.util.HibernateUtil;

public class StudentStressTest extends AbstractJavaSamplerClient {

	private Map<String, String> mapParams = new HashMap<String, String>();
	private SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

	public StudentStressTest() {
		super();
	}

	@Override
	public void setupTest(JavaSamplerContext context) {
		for (Iterator<String> it = context.getParameterNamesIterator(); it.hasNext();) {
			String paramName = it.next();
			mapParams.put(paramName, context.getParameter(paramName));
		}
	}

	public SampleResult runTest(JavaSamplerContext context) {
		SampleResult result = new SampleResult();

		try {

			JMeterVariables vars = JMeterContextService.getContext().getVariables();
			vars.put("demo", "demoVariableContent");

			result.sampleStart();

			Student student = new Student();
			student.setStudentname(mapParams.get("name") + " " + new Date().getTime());
			Session session = sessionFactory.openSession();
			session.save(student);
			session.flush();
			session.close();

			result.sampleEnd();

			result.setSuccessful(true);
			result.setSampleLabel("SUCCESS: " + student.getStudentname());

		} catch (Throwable e) {
			result.sampleEnd();
			result.setSampleLabel("FAILED: '" + e.getMessage() + "' || " + e.toString());
			result.setSuccessful(false);

			e.printStackTrace();
		}

		return result;
	}

	@Override
	public Arguments getDefaultParameters() {
		Arguments params = new Arguments();
		params.addArgument("name", "noboby");
		return params;
	}
}

Compiler et packager votre projet et copier le jar dans le répertoire $JMETER_HOME/lib/ext ainsi que les jars suivant:

On peut maintenant passer à la partie la plus intéressante, lancer Jmeter puis créer:

un groupe d’unités (Moteurs d’utilisateurs/Groupes d’unités) auquel vous ajouterez:

    1. une requête Java (Echantillons/Requête Java)
    2. un tableau de résultats (Récepteurs/Tableau de résultats)
    3. un rapport consolidé (Récepteurs/Rapport consolidé)
Vous obtiendrez alors un arborescence comme dans la screenshot ci-dessous:

Dans le requête Java, sélectionner la classe  »fr.jahroots.xperiments.jmeter.StudentStressTest ». Vous pouvez si vous le souhaiter changer le nom qui sera enregistrer en base.

Il faut ensuite définir notre tir, nous allons réaliser la simulation d’un utilisateur qui réalise 5 fois l’insertion en base:

On peut maintenant lancer notre tir et visualiser comment se sont déroulées les itérations grâce au tableau des résulats:

Encore plus intéressant, le rapport consolidé que je vous laisse découvrir ;).

Bon je sais à quel point c’est fastidieux de réécrire un tutoriel donc j’ai mis les sources à votre disposition ici :).

Publicités

Une réflexion sur “Mesurer la performance d’une classe Java avec JMeter

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s