Archives mensuelles : décembre 2013

JQM : un serveur de batch asynchrones en Java

JQM (Job Queue Management) est un gestionnaire de batch sous licence Apache qui permet de traiter sur des noeuds de traitement répartis toutes les tâches potentiellement longues qui ne sont pas désirables dans un serveur d’application à travers un système de files de priorité. Ce logiciel s’adresse à toute application qui souhaite gérer l’exécution de ses tâches hors du serveur d’application.

Une tâche peut être déclenchée depuis un appel Web Service ou une API par une application web, un ordonnanceur ou un flux d’interface.

L’outil propose de nombreuses fonctionnalités comme l’arrêt d’une tâche, la récupération de fichiers générés, la priorisation d’une tâche et bien d’autres. JQM a été développé en Java SE 1.6, utilise Hibernate/JPA 2.0 comme ORM, et une base de donnée comme référentiel de configuration et file d’attente des traitements. JQM est compatible avec les bases HSQL, MySQL et Oracle, les serveurs d’application WebSphere et Glassfish (prochainement Tomcat) pour l’API cliente et gère les ressources JNDI pour les bases de données et les brokers de messages.

L’outil est compatible avec les projets Maven et tout particulièrement la gestion des dépendances et des projets parents.
Architecture

JQM est composé de trois grandes parties :

  • les moteurs de traitements (des JVM standalone) qui exécutent les tâches. Il est possible de déployer plusieurs moteurs (ou noeuds) de traitements pour des raisons de performance ou de haute disponibilité
  • une base de données qui joue le rôle de file de traitement et de référentiel de configuration
  • les clients (une application Web dans un serveur d’application, une ligne de commande, un ordonnanceur, un autre job JQM etc.) qui soumettent des jobs à JQM

Les noeuds de traitement sont reliés à des files de traitement en base de données et ont chacun un intervalle de polling et un nombre défini de jobs pouvant tourner simultanément.

Par exemple:

  • VIPqueue = 10 jobs simultanées + intervalle de polling de 1 seconde
  • SLOWqueue = 3 jobs en simultanés + intervalle de polling de 15 min
schema_jqm

Cycle de vie d’une tache

Le cycle de vie d’un job passe par quatre états différents.

Après avoir été ajoutée à la file d’attente, la tâche prend le status « SUBMITTED ». Une fois  que le job est « attrapé » par un noeud, son statut passe à l’état « ATTRIBUTED » suivi de  « RUNNING » une fois que l’exécution de celui-ci a commencé.

Le job à la fin de son execution a deux états possibles, « CRASHED » si le job n’a pas  fonctionné correctement ou « ENDED » si tout le processus s’est déroulé correctement.

cycle_of_life_JQM

 

Fonctionnalités 

Pour les développeurs
  • Pour les développeurs de traitement
Un job est défini comme tel une fois qu’il « extends » de la classe JobBase de l’API jqm-api. Au sein d’un job, il est possible de récupérer des ressources via JNDI (base de données, broker de message, répertoire de traitement…), d’envoyer une progression, un message de log ou de mettre en file un autre job.
  • Pour les clients des traitements

Il existe plusieurs moyens d’utiliser JQM.

– Par le biais de l’API jqm-clientapi qui permet d’avoir toutes les fonctionnalités existantes, à savoir la possibilité de mettre un job en file, de regarder son état, de l’annuler, de le changer de file et bien d’autres.
  • Par le biais d’un web service
  • Par une interface en ligne de commande
  • Par une IHM web (très frustre à l’heure actuelle)

Pour les administrateurs

Un administrateur à la possibilité de consulter les logs, de gérer les connexions JNDI, de paramétrer les associations entre les jobs et  les files.

Exemple de job

public class Caller extends JobBase
{
    @Override
    public void start()
    {
        Map<String, String> params = new HashMap<String, String>();
        p.put(“myParam1”, “Pouet”);
        p.put(“myParam2”, “Tut tut”);
        // enQueue is a JobBase method.
        // It is used to enqueue a Job, here “Called”.
        enQueue(“CalledJob”, “Bob”, null, null, null, null, null,
                 null, null, null, null, params);
        }
}
 

Exemple d’intégration de JQM dans un SI

Dans cet exemple, JQM est utilisé pour gérer une intégration au fil de l’eau de message dans un ERP qui ne possède qu’une interface d’entrée de type table / prodédure stockée.
JQM joue un rôle de « joint de dilatation » entre un système évènementiel qui gère des pics à 200 000 messages par heure et une interface de type procédure stockée qui traite des données en masse mais ne se prête pas à de nombreuses exécutions simultanées.
Chaque message est traité par un thread d’un conteneur MDB (Message Driven Bean) et déclenche un job JQM. La file de job JQM est paramétrée pour n’exécuter qu’un seul job à la fois et annuler les lancements surnuméraires. Le job lance la prodédure stockée de l’ERP qui traite toutes les données en attente dans la table d’interface.
En pic, plusieurs centaines de messages n’occasionneront qu’un ou deux lancement de la procédure stockée qui traitera en masse les données. Le système permet ainsi de rester très réactif en période creuse (au contraire des systèmes de type batch cyclique) tout en permettant la montée en charge lors des pics.

 

integration_jqm

Origine du projet

Le projet a été développé par la société enioka dans le cadre d’un projet pour l’un de ses clients pour l’intégration d’un ERP.
Suite à la réalisation de ce projet, il a été convenu que JQM deviendrait open source afin de combler le manque actuel de ce type d’outils libres dans un contexte java SE/EE 6.

Le code source et la documentation sont disponibles sur Github.