25/05/2023
Dans le monde complexe du développement d'applications d'entreprise, la communication entre les différents composants est un défi constant. Les systèmes d'appel de procédure à distance (RPC), tels que Java RMI, bien que puissants, imposent un modèle de communication synchrone: l'appelant doit bloquer et attendre la fin de l'exécution de la méthode appelée. Cela crée un couplage fort entre les applications, rendant difficile la construction de systèmes distribués flexibles sans recourir à des techniques de multithreading complexes. En d'autres termes, les systèmes RPC exigent que le client et le serveur soient disponibles simultanément, ce qui n'est pas toujours réalisable ni souhaitable dans certaines architectures. C'est ici que les systèmes de Middleware Orienté Message (MOM) entrent en jeu, offrant une solution élégante à ces problèmes. Basés sur un modèle d'interaction asynchrone, ils fournissent l'abstraction d'une file d'attente de messages accessible via un réseau. Il est important de noter que la messagerie dont il est question ici concerne les requêtes ou événements asynchrones consommés par des applications d'entreprise, et non la communication humaine comme dans le courrier électronique. Ces messages contiennent des données formatées décrivant des actions métier spécifiques.

- Qu'est-ce que le Java Message Service (JMS) ?
- Architecture d'une Application JMS
- Modèles de Livraison de Messages
- Le Modèle de Programmation JMS en Détail
- Messagerie Fiable et Performances
- Sun Java System Message Queue: Un Fournisseur JMS Concret
- Message-Driven Beans (MDBs): L'Intégration JMS dans J2EE
- Conclusion
- Questions Fréquentes (FAQ) sur JMS
Qu'est-ce que le Java Message Service (JMS) ?
Le Java Message Service (JMS), conçu par Sun Microsystems et plusieurs autres entreprises dans le cadre du Java Community Process (JSR 914), est la première API de messagerie d'entreprise à avoir bénéficié d'un large soutien de l'industrie. JMS a été créé pour simplifier le développement d'applications métier capables d'envoyer et de recevoir des données et événements métier de manière asynchrone. Il définit une API de messagerie d'entreprise commune, conçue pour être facilement et efficacement prise en charge par une vaste gamme de produits de messagerie d'entreprise. JMS prend en charge les deux modèles de messagerie fondamentaux: le point-à-point (files d'attente) et la publication-abonnement (sujets).
L'objectif principal de JMS est de permettre aux applications Java d'utiliser les systèmes de messagerie d'entreprise, et surtout, de fournir un moyen commun pour les applications Java d'accéder à ces systèmes. JMS s'inscrit dans la catégorie des middlewares, et plus spécifiquement des middlewares orientés message (MOM), qui représentent un niveau d'abstraction relativement bas, servant de fondation à des couches complémentaires telles que les adaptateurs de bases de données et d'applications, le traitement d'événements et l'automatisation des processus métier. Le MOM devient un composant essentiel pour l'intégration des opérations intra-entreprise, car il permet de combiner des composants métier séparés en un système fiable et flexible.
JMS définit un ensemble d'interfaces et de sémantiques qui permettent aux applications Java de communiquer avec d'autres implémentations de messagerie. Une implémentation JMS est connue sous le nom de fournisseur JMS. JMS facilite la courbe d'apprentissage en minimisant l'ensemble des concepts qu'un développeur Java doit maîtriser pour utiliser les produits de messagerie d'entreprise, tout en maximisant la portabilité des applications de messagerie.
Architecture d'une Application JMS
Une application JMS est typiquement composée des éléments suivants :
- Un fournisseur JMS : Un système de messagerie qui implémente la spécification JMS. C'est le cœur de l'infrastructure de messagerie.
- Des clients JMS : Les applications Java qui sont responsables de l'envoi (producteurs) et de la réception (consommateurs) des messages.
- Des messages : Les objets utilisés pour communiquer des informations entre les clients JMS. Ils contiennent les données métier.
- Des objets administrés : Des objets JMS préconfigurés, généralement créés par un administrateur, pour être utilisés par les clients JMS. Cela inclut les fabriques de connexion (ConnectionFactory) et les destinations (Destination).
Modèles de Livraison de Messages
JMS prend en charge deux modèles distincts pour la livraison des messages, chacun adapté à des scénarios de communication différents :
Modèle Point-à-Point (File d'Attente - Queue)
Dans ce modèle, un message est livré d'un producteur à un seul consommateur. Les messages sont envoyés à une destination de type file d'attente (Queue). Ensuite, ils sont livrés à l'un des consommateurs enregistrés pour cette file d'attente. Bien qu'un nombre quelconque de producteurs puisse envoyer des messages à la file d'attente, chaque message est garanti d'être livré et consommé par un seul consommateur. Si aucun consommateur n'est enregistré pour consommer les messages, la file d'attente les conserve jusqu'à ce qu'un consommateur s'enregistre pour les traiter. Ce modèle est idéal pour les tâches qui ne doivent être traitées qu'une seule fois, comme le traitement des commandes ou la gestion des paiements.
Modèle Publication/Abonnement (Sujet - Topic)
Dans ce modèle, un message est livré d'un producteur à un nombre quelconque de consommateurs. Les messages sont envoyés à une destination de type sujet (Topic), puis livrés à tous les consommateurs actifs qui se sont abonnés à ce sujet. De plus, un nombre quelconque de producteurs peut envoyer des messages à une destination de sujet, et chaque message peut être livré à un nombre quelconque d'abonnés. Si aucun consommateur n'est enregistré, la destination du sujet ne conserve pas les messages, sauf si elle dispose d'un abonnement durable pour les consommateurs inactifs. Un abonnement durable représente un consommateur enregistré auprès de la destination du sujet qui peut être inactif au moment où les messages sont envoyés au sujet, garantissant ainsi qu'il recevra les messages manqués lors de sa reconnexion. Ce modèle est parfait pour les scénarios de diffusion, comme la distribution de mises à jour de prix ou de notifications d'événements.
| Caractéristique | Point-à-Point (Files d'attente) | Publication/Abonnement (Sujets) |
|---|---|---|
| Nombre de consommateurs par message | Un seul | Zéro ou plusieurs |
| Conservation des messages sans consommateur | Oui (dans la file) | Non (sauf abonnement durable) |
| Nature de la communication | Tâche unique, traitement exclusif | Diffusion, notification |
| Exemples d'utilisation | Traitement de commandes, workflow | Alertes boursières, actualités, événements |
Le Modèle de Programmation JMS en Détail
Une application JMS consiste en un ensemble de messages définis par l'application et un ensemble de clients qui les échangent. Les clients JMS interagissent en envoyant et en recevant des messages à l'aide de l'API JMS. Un message JMS est composé de trois parties principales: l'en-tête, les propriétés et le corps.
Structure d'un Message JMS
- L'en-tête (Header) : Obligatoire pour chaque message, l'en-tête contient des informations utilisées pour le routage et l'identification des messages. Certains de ces champs sont définis automatiquement par le fournisseur JMS lors de la production et de la livraison d'un message, tandis que d'autres sont définis par le client message par message.
- Les propriétés (Properties) : Optionnelles, les propriétés fournissent des valeurs que les clients peuvent utiliser pour filtrer les messages. Elles offrent des informations supplémentaires sur les données, telles que le processus qui les a créées ou l'heure de leur création. Les propriétés peuvent être considérées comme une extension de l'en-tête et consistent en des paires nom/valeur. Grâce aux propriétés, les clients peuvent affiner leur sélection de messages en spécifiant certaines valeurs qui agissent comme critères de sélection.
- Le corps (Body) : Également optionnel, le corps contient les données réelles à échanger. La spécification JMS définit six types ou classes de messages que tout fournisseur JMS doit prendre en charge :
Message: Représente un message sans corps de message.StreamMessage: Un message dont le corps contient un flux de types primitifs Java. Il est écrit et lu séquentiellement.MapMessage: Un message dont le corps contient un ensemble de paires nom/valeur. L'ordre des entrées n'est pas défini.TextMessage: Un message dont le corps contient une chaîne Java, comme un message XML.ObjectMessage: Un message dont le corps contient un objet Java sérialisé.BytesMessage: Un message dont le corps contient un flux d'octets non interprétés. Ce type est souvent utilisé pour correspondre à des formats de messages existants ou pour des performances maximales où les données sont traitées comme un flux brut.
Étapes pour Produire et Consommer des Messages
Le développement de clients JMS pour produire et consommer des messages suit un ensemble d'étapes communes et spécifiques. Voici une vue d'ensemble :
Étapes Communes (Producteur et Consommateur) :
- Obtenir une
ConnectionFactory: Utilisez le Java Naming and Directory Interface (JNDI) pour trouver un objetConnectionFactory(QueueConnectionFactorypour P2P ouTopicConnectionFactorypour Pub/Sub), ou instanciez-le directement. - Créer une
Connection: Utilisez l'objetConnectionFactorypour créer uneConnectionau fournisseur JMS. Il est crucial de fermer toutes les connexions créées en utilisant la méthodeConnection.close(). - Créer une ou plusieurs
Session: Utilisez l'objetConnectionpour créer uneSession. Une session fournit un contexte transactionnel pour regrouper un ensemble d'envois et de réceptions en une unité de travail atomique. La méthodecreateSession()prend des arguments pour spécifier si la session est transactionnelle et le mode d'acquittement des messages. - Obtenir une
Destination: Utilisez JNDI pour trouver des objetsDestination(QueueouTopic), ou instanciez-les directement et configurez leurs attributs. La destination est la source ou la cible des messages.
Étapes Spécifiques au Producteur :
- Créer un
MessageProducer: Utilisez uneSessionet un objetDestinationpour créer l'objetMessageProducernécessaire, utilisé pour envoyer des messages à une destination. - Créer le Message : Instanciez un objet message du type souhaité (ex:
TextMessage,ObjectMessage) et définissez son contenu. - Envoyer le Message : Utilisez la méthode
producer.send(message)pour envoyer le message à la destination.
Étapes Spécifiques au Consommateur :
- Créer un
MessageConsumer: Utilisez un objetSessionet un objetDestinationpour créer les objetsMessageConsumernécessaires, utilisés pour recevoir les messages. Pour les sujets, vous pouvez utiliserSession.createDurableSubscriber()pour un abonné durable. - Démarrer la
Connection: La livraison des messages ne commence pas tant que la connexion n'a pas été démarrée. Appelez la méthodeconnection.start(). - Recevoir les Messages :
- Synchrone : Utilisez la méthode
consumer.receive(). Cette méthode bloque jusqu'à ce qu'un message soit disponible ou qu'un délai d'attente (si spécifié) expire. - Asynchrone : Instanciez un objet
MessageListener(qui implémente la méthodeonMessage()) et enregistrez-le avec leMessageConsumeren utilisantsetMessageListener(). Le fournisseur JMS invoque automatiquementonMessage()chaque fois qu'un message est livré, sans bloquer le thread de l'application.
- Synchrone : Utilisez la méthode
| Caractéristique | Consommation Synchrone | Consommation Asynchrone |
|---|---|---|
| Méthode principale | consumer.receive() | MessageListener.onMessage() |
| Comportement du thread | Bloquant (attend un message ou un timeout) | Non bloquant (rappel via listener) |
| Traitement des messages | Un message à la fois | Événementiel, potentiellement concurrent |
| Complexité | Plus simple pour des traitements séquentiels | Nécessite une gestion des threads et des états pour la concurrence |
| Cas d'usage | Quand une réponse immédiate ou séquentielle est requise | Traitement en arrière-plan, flux continu de messages |
Messagerie Fiable et Performances
JMS définit deux modes de livraison qui permettent aux développeurs de faire un compromis entre la fiabilité et la performance :
- Messages persistants : Garantis d'être consommés avec succès une seule et unique fois. Les messages ne sont pas perdus, même en cas de panne du fournisseur JMS. Ce mode assure la durabilité et l'intégrité des messages, mais au prix d'une surcharge plus importante en termes de bande passante et de ressources système, car les messages doivent être stockés sur un support durable.
- Messages non persistants : Garantis d'être livrés au plus une fois. La perte de messages n'est pas une préoccupation majeure dans ce scénario. Ce mode privilégie la performance, car les messages ne sont pas écrits sur disque et sont traités plus rapidement. Il est adapté aux données transitoires ou aux flux d'événements où la perte occasionnelle d'un message est acceptable.
Le choix entre ces deux modes dépend des exigences spécifiques de l'application en matière de résilience des données. Plus la livraison des messages est fiable, plus la bande passante et la surcharge nécessaires pour atteindre cette fiabilité sont importantes. Les performances peuvent être maximisées en produisant des messages non persistants, ou la fiabilité peut être maximisée en produisant des messages persistants.
Sun Java System Message Queue: Un Fournisseur JMS Concret
Sun, l'un des principaux concepteurs de JMS, propose depuis 1999 une implémentation de production de JMS. Le Sun Java System Message Queue, anciennement connu sous les noms de Java Message Queue, iPlanet Message Queue for Java et Sun ONE Message Queue, est un produit de messagerie complet. Il répond à tous les besoins de messagerie d'entreprise grâce à son support des modèles de messagerie point-à-point et publication/abonnement, ainsi qu'à son support de la messagerie synchrone et asynchrone.

Grâce à ce produit, les processus s'exécutant sur différentes plateformes et systèmes d'exploitation peuvent se connecter à un service Message Queue commun pour envoyer et recevoir des informations. Les développeurs d'applications peuvent ainsi se concentrer sur la logique métier de leurs applications plutôt que sur les détails de bas niveau de la mise en œuvre d'une communication fiable sur le réseau.
Ce produit est un serveur de messages d'entreprise leader pour l'intégration métier, offrant une solution de messagerie basée sur les standards. Il est disponible en deux éditions :
- Platform Edition : Il s'agit à la fois de l'implémentation de référence de la spécification JMS 1.1 et d'un produit autonome. Conçue pour les déploiements à petite échelle et les environnements de développement, cette édition est incluse dans l'implémentation de référence J2EE 1.4 et le Sun Java System Application Server Platform Edition 8. Elle est également disponible en téléchargement gratuit pour une utilisation en tant que produit autonome.
- Enterprise Edition : Un système de messagerie haute performance conçu pour les déploiements d'entreprise à grande échelle, visant à intégrer des applications disparates. Il inclut des fonctionnalités d'entreprise clés telles que la scalabilité, la fiabilité et une sécurité avancée.
Il est important de noter que JMS lui-même ne définit pas de fonctionnalités concernant l'équilibrage de charge, la tolérance aux pannes, la sécurité et l'administration. Ces mécanismes doivent être fournis par les fournisseurs JMS. Cependant, si vous téléchargez la Platform Edition gratuite, elle est livrée avec un essai de 90 jours de l'Enterprise Edition.
Le produit inclut un adaptateur de ressources compatible J2EE 1.4, vous permettant d'utiliser Sun Java System Message Queue comme fournisseur JMS pour tout serveur d'applications compatible avec la technologie J2EE 1.4. Cela permet aux entreprises de maximiser leurs investissements dans les actifs informatiques actuels en continuant à utiliser leur serveur d'applications existant tout en tirant parti des avantages de Sun Java System Message Queue.
Test de l'Installation de Sun Java System Message Queue
Pour tester votre installation, suivez ces étapes simples :
- Exécuter le broker : Accédez au répertoire bin de votre installation et exécutez la commande: imqbrokerd -tty. L'option -tty affiche tous les messages de journalisation sur la console, en plus du fichier journal. Le broker démarrera et affichera quelques messages avant d'indiquer "imqbroker@hostname:7676 ready".
- Tester le broker : Dans une fenêtre séparée, exécutez la commande: imqcmd query bkr -u admin -p admin. Si tout est en ordre, des informations détaillées sur le broker s'afficheront, confirmant son bon fonctionnement.
Message-Driven Beans (MDBs): L'Intégration JMS dans J2EE
JMS est une API et un service obligatoires dans la plateforme J2EE. Un excellent exemple de son intégration est le Message-Driven Bean (MDB), l'un des types d'EJB spécifiés dans EJB 2.0/2.1, aux côtés des session beans et des entity beans (qui ne peuvent être appelés que de manière synchrone).
Un JMS Message-Driven Bean (MDB) est un consommateur de messages JMS qui implémente l'interface MessageListener de JMS. La méthode onMessage() est invoquée lorsque un message est reçu par le conteneur MDB. Il est important de noter que vous n'invoquez pas de méthodes distantes sur les MDBs (contrairement aux autres Enterprise Beans) et, par conséquent, aucune interface "home" ou "remote" ne leur est associée. Il convient également de souligner qu'avec J2EE 1.4, les MDBs ne sont pas limités à JMS ; une multiplicité d'interfaces MDB peuvent être déclarées et consommées par des composants d'application implémentant ces interfaces.
Conclusion
Le Java Message Service (JMS) simplifie considérablement le développement d'applications d'entreprise capables d'envoyer et de recevoir des données et des événements métier de manière asynchrone. En définissant une API de messagerie d'entreprise commune, JMS assure une prise en charge facile et efficace par une large gamme de produits de messagerie. Il prend en charge les deux modèles de messagerie essentiels: le point-à-point (files d'attente) et la publication-abonnement (sujets), offrant une flexibilité précieuse pour diverses architectures d'intégration. Cet article a fourni une introduction rapide et un tutoriel au fonctionnement de JMS et à son modèle de programmation.
La spécification JMS a été implémentée par la plupart des serveurs d'applications et autres éditeurs de logiciels. Parmi ces implémentations, le Sun Java System Message Queue Platform Edition se distingue comme un serveur de messages d'entreprise conçu pour les déploiements à petite échelle et les environnements de développement. Il implémente la spécification JMS 1.1 et prend en charge SOAP. Bien que ce logiciel soit disponible gratuitement, il est important de noter qu'il n'inclut pas les avantages clés des entreprises tels que la scalabilité, la fiabilité et la sécurité avancée. Ces fonctionnalités sont disponibles dans l'Enterprise Edition du Java System Message Queue, dont une version d'essai de 90 jours est incluse dans la Platform Edition.
Questions Fréquentes (FAQ) sur JMS
- Pourquoi utiliser JMS plutôt que des appels RPC directs ?
- JMS favorise le découplage des applications. Contrairement aux RPC qui nécessitent une disponibilité simultanée du client et du serveur, JMS permet une communication asynchrone. Cela signifie que les applications peuvent envoyer des messages sans attendre de réponse immédiate, améliorant la résilience, la scalabilité et la flexibilité du système. En cas de panne d'un composant, les messages sont conservés et traités lorsque le composant redevient disponible.
- Quelle est la différence fondamentale entre une file d'attente (Queue) et un sujet (Topic) ?
- Une file d'attente (modèle point-à-point) garantit qu'un message envoyé par un producteur sera consommé par un seul et unique consommateur. C'est idéal pour le traitement de tâches uniques. Un sujet (modèle publication-abonnement) permet à un message envoyé par un producteur d'être diffusé à plusieurs consommateurs abonnés. C'est parfait pour les scénarios de diffusion d'informations.
- JMS gère-t-il la sécurité, l'équilibrage de charge ou la tolérance aux pannes ?
- Non, la spécification JMS elle-même ne définit pas ces fonctionnalités. Ce sont les fournisseurs JMS (comme Sun Java System Message Queue, Apache ActiveMQ, IBM MQ, etc.) qui doivent implémenter ces mécanismes avancés pour offrir des solutions complètes et robustes aux entreprises. JMS fournit l'API standard, mais les fonctionnalités d'infrastructure sous-jacentes relèvent du fournisseur.
- Qu'est-ce qu'un Message-Driven Bean (MDB) et comment est-il lié à JMS ?
- Un Message-Driven Bean (MDB) est un type d'Enterprise JavaBean (EJB) qui agit comme un consommateur asynchrone de messages. Il est étroitement lié à JMS car il est souvent configuré pour écouter des destinations JMS (files d'attente ou sujets). Lorsqu'un message arrive sur la destination écoutée, le conteneur EJB invoque automatiquement la méthode
onMessage()du MDB pour traiter le message, offrant ainsi un moyen simple et standardisé d'intégrer la messagerie asynchrone dans les applications J2EE. - Peut-on mélanger les modes de consommation (synchrone et asynchrone) dans une même application JMS ?
- Oui, une application peut utiliser les deux modes de consommation. Un client JMS peut choisir de consommer des messages de manière synchrone (en appelant
receive()) ou asynchrone (en enregistrant unMessageListener) en fonction de ses besoins spécifiques pour différentes destinations ou flux de messages.
Si tu souhaites découvrir d'autres articles similaires à JMS: Révolutionner la Communication Asynchrone en Java, tu peux visiter la catégorie Massages.
