1. Communication asynchrone
Les technologies RMI, Hessian et autres avec lesquelles nous sommes en contact sont en contact avec tous les mécanismes de communication synchrones. Lorsque le client appelle une méthode distante, le client doit attendre la fin de la méthode distante avant de continuer à s'exécuter. Le client sera bloqué pendant cette période (cela provoque une très mauvaise expérience utilisateur).
(Communication synchrone)
La communication synchrone n'est pas le seul moyen d'interagir entre les programmes. Dans le mécanisme de communication asynchrone, le client n'a pas besoin d'attendre que le service traite le message, peut continuer à exécuter et enfin recevoir et traiter le message.
(Communication asynchrone)
Avantages de la communication asynchrone
Pas besoin d'attendre. Le client n'a qu'à envoyer le message au courtier de messages et peut continuer à effectuer d'autres tâches sans attendre, et est sûr que le message sera livré à la destination correspondante.
Axé sur les messages et découplage. Le client n'a pas à s'inquiéter des spécifications d'interface du service distant, il n'a qu'à mettre le message dans la file d'attente du message et d'obtenir les résultats.
2. JMS
1. Introduction
Avant que JMS ne soit émergé, chaque courtier de messages avait une implémentation différente, ce qui a rendu le code de message entre différents courtiers difficiles à être universels. JMS (Java Message Service) est une norme qui définit une API commune qui utilise des courtiers de messages. Autrement dit, toutes les implémentations conformes aux spécifications utilisent une interface commune, similaire à JDBC fournissant une interface commune pour les opérations de base de données.
Plusieurs éléments importants de JMS:
Destination: le canal auquel le message est envoyé à partir de l'expéditeur.
ConnectionFactory: Connection Factory, utilisé pour créer des objets connectés.
Connexion: Interface de connexion, utilisée pour créer la session.
Session: Interface de session, utilisée pour créer l'expéditeur, destinataire du message et l'objet de message lui-même.
MessageConsumer: le consommateur du message.
MessageProducer: le producteur du message.
XXXMessage: Divers types d'objets de message, y compris 5 types: ByteMessage, MapMessage, ObjectMessage, StreamMessage et TextMessage.
2. Modèle de message JMS
Différents systèmes de messages ont des modèles de messages différents. JMS fournit deux modèles: file d'attente (point à point) et sujet (publier / abonner).
Modèle de file d'attente JMS (point à point)
Dans un modèle peer-to-peer, le producteur de messages produit un message et l'envoie dans la file d'attente, et le consommateur de message le sort ensuite de la file d'attente et consomme le message, mais ne peut pas être consommé à plusieurs reprises.
Comme indiqué dans l'image:
Expéditeur 1, expéditeur 2 et expéditeur 3 Envoient chacun un message au serveur;
Les messages 1, 2 et 3 constitueront une file d'attente dans l'ordre, et les messages dans la file d'attente ne savent pas quel destinataire sera consommé;
Les récepteurs 1, 2 et 3 respectent respectivement un message de la file d'attente pour la consommation. Chaque fois qu'un message est récupéré, la file d'attente supprimera le message, ce qui garantit que le message ne sera pas consommé à plusieurs reprises.
Le modèle de file d'attente JMS est également devenu un modèle P2P (point à point).
Modèle de sujet JMS (publier / abonner)
La plus grande différence entre le modèle de sujet JMS et le modèle de file d'attente JMS réside dans la partie de la réception du message. Le modèle de sujet est similaire à un compte officiel de WeChat. Les destinataires qui souscrivent au compte officiel peuvent recevoir des messages poussés par le compte officiel.
Comme indiqué dans l'image:
Publishers 1, 2, 3 Publier 3 sujets 1, 2, 3 respectivement;
De cette façon, le groupe d'utilisateurs qui souscrit au sujet 1: abonnés 1, 2, 3 peut recevoir des messages du sujet 1; De même, les abonnés 4, 5, 6 peuvent recevoir des messages du sujet 2, et les abonnés 7, 8, 9 peuvent recevoir des messages du sujet 3.
Le modèle de sujet JMS est également devenu le modèle PUS / Sub.
Comparaison de chaque élément dans les deux modes:
3. Modèle de programmation JMS traditionnel
Producteur:
(1) créer une connexion Connection ConnectionFactory;
(2) créer une connexion à l'aide de l'usine de connexion;
(3) démarrer la connexion;
(4) Créer une session;
(5) Créez la destination pour l'envoi de messages;
(6) créer un producteur;
(7) Créer du type de message et du contenu du message;
(8) Envoyer un message;
Consommateur:
(1) créer une connexion Connection ConnectionFactory;
(2) créer une connexion à l'aide de l'usine de connexion;
(3) démarrer la connexion;
(4) Créer une session;
(5) Créez la destination pour l'envoi de messages;
(6) Créer un consommateur (7) Créer un type de message;
(8) recevoir des messages;
3. Introduction à ActiveMQ
ActiveMQ est le bus de message open source le plus populaire et le plus puissant produit par Apache. ActiveMQ est une implémentation de fournisseur JMS qui prend en charge les spécifications JMS1.1 et J2EE 1.4. Bien que la spécification JMS ait été introduite depuis longtemps, JMS joue toujours une position spéciale parmi les applications J2EE d'aujourd'hui.
ActiveMQ principaux Caractéristiques:
Rédaction des clients dans plusieurs langues et protocoles. Langues: Java, C, C ++, C #, Ruby, Perl, Python, PHP. Protocole d'application:
OpenWire, Stomp Rest, Notification WS, XMPP, AMQP
Prise en charge pleinement pour les spécifications JMS1.1 et J2EE 1.4 (persistance, messages XA, transactions)
Pour le support de printemps, ActiveMQ peut être facilement intégré dans le système à l'aide de Spring, et prend également en charge les fonctionnalités de Spring 2.0. Passé le test des serveurs J2EE communs (comme Geronimo, Jboss 4, Glassfish, Weblogic). Grâce à la configuration des adaptateurs de ressources JCA 1.5, ActiveMQ peut être déployé automatiquement sur n'importe quel serveur commercial J2EE 1.4 compatible et prend en charge plusieurs protocoles de transmission: In-VM, TCP, SSL, NIO, UDP, JGroups, JXTA
Prend en charge la persistance des messages à grande vitesse via JDBC et Journal, ce qui garantit des grappes de haute performance, un client client et une prise en charge point à point pour Ajax
Prise en charge de l'intégration avec axe pour appeler facilement le fournisseur JMS intégré pour tester
4. CALICEMQ COMBAT réel
Voyons comment ActiveMQ implémente une file d'attente de messages simple.
Modèle de programmation JMS traditionnel
1. Implémentation du code du modèle de file d'attente JMS:
Producteur:
package com.wgs.mq.queue; import org.apache.activemq.activemqconnectionfactory; import javax.jms. *; / ** * créé par genshenwang.nomico le 2017/10/19. * / classe publique activeMQProducer {private static final string url = "tcp: // localhost: 61616"; private static final string queue_name = "queue-name"; public static void main (String [] args) lance jmsexception {// 1 créer une connexion connexion connexionFactoryConnectionFactoryFactory = new ActiveMQConnectionFactory (URL); // 2 Créer une connexion à l'aide d'une connexion Connexion Connexion Connexion = ConnectionFactory.CreateConnection (); // 3 Démarrer la connexion Connection.Start (); // 4 Créer une session Session Session = Connection.CreateSession (False, session.Auto_acknowledge); // 5 Créer une destination pour l'envoi d'une destination de message = Session.Create. producteur messageProducer MessageProducer = session.CreateProducer (Destination); // 7 Créer du message TextMessage TextMessage = session.CreateTextMessage (); pour (int i = 1; i <= 100; i ++) {// 8 Créer le contenu du message textMessage.SeTText ("Sender- 1 -Send Message:" + i); // 9 Envoyer un message MessageProducer.Send (textMessage);} System.out.println ("Message envoyé avec succès"); session.close (); Connection.close ();}}Conusmer:
package com.wgs.mq.queue; import org.apache.activemq.activemqconnectionfactory; import javax.jms. *; / ** * créé par genshenwang.nomico le 2017/10/19. * / classe publique activeMQConsumer {private static final string url = "tcp: // localhost: 61616"; private static final string queue_name = "queue-name"; public static void main (string [] args) lance jmsexception {/ 1 1 création une connexion connexion ConnectionFactoryConnectionFactoryFactory = new ActiveMQConnectionFactory (URL); // 2 Créer une connexion à l'aide d'une connexion Connexion Connexion Connexion = ConnectionFactory.CreateConnection (); // 3 Démarrer la connexion Connection.Start (); // 4 Créer une session Session Session = Connection.CreateSession (False, session.Auto_acknowledge); // 5 Créer une destination pour l'envoi d'une destination de message = Session.Create. Consumer MessageConsumer MessageConsumer = Session.CreateConsumer (destination); MessageConsumer.SetMessageListener (new MessageListener () {public void OnMessage (message de message) {// 7 Créer un message de messagerie Message.out.println ("Consumer- 1 - reçoit le message: [" + textran {e.printStackTrace ();}}});}}2. Implémentation du code du modèle de sujet JMS:
Producteur:
package com.wgs.mq.topic; import org.apache.activemq.activemqconnectionfactory; import javax.jms. *; / ** * Mode d'abonnement publié * créé par genshenwang.nomico le 2017/10/19. * / classe publique activeMQProducer {private static final String url = "tcp: // localhost: 61616"; private static final String topic_name = "topic-name"; public static void Main (String [] args) lance JMSException {// 1 Création d'une connexion ConnectionFactory (URL); Créer une connexion à l'aide d'une connexion connexion connexion connexion = connectionFactory.CreateConnection (); // 3 Démarrer la connexion Connection.Start (); // 4 Créer une session Session Session = Connection.CreateSession (false, session.Auto_ackNowledge); // 5 Créer une destination pour l'envoi de messages avec une destination de thème = Session.CreateTopic (topic_name); // 6 Créer un producteur de destination messageProducer = session.CreateProducer (Destination); // 7 Créez un message TextMessage TextMessage = Session.CreateExtMessage (); pour (int i = 1; i <= 100; i ++) {// 8 Créer le contenu du message textMessage.SeTText ("Sender- 1 -Send Message:" + i); // 9 Envoyer un message MessageProducer.Send (textMessage);} System.out.println ("Message envoyé avec succès"); session.close (); Connection.close ();}}Consommateur:
package com.wgs.mq.topic; import org.apache.activemq.activemqconnectionfactory; import javax.jms. *; / ** * Mode d'abonnement publié * créé par genshenwang.nomico le 2017/10/19. * / classe publique activeMQConsumer {private static final string url = "tcp: // localhost: 61616"; private static final String topic_name = "topic-name"; public static void Main (String [] args) lance JMSException {// 1 Créer une connexion ConnectionFactory (URL); Créer une connexion à l'aide d'une connexion connexion connexion connexion = connectionFactory.CreateConnection (); // 3 Démarrez la connexion.Start (); // 4 Créer une session Session Session = Connection.CreateSession (False, session.Auto_ackNowledge); // 5 Créer la destination pour l'envoi de la destination du message = session.CreateTopic (topic_name); // 6 Créer un message MessagConSumère Consumer MessageConsumer = session.CreateConsumer (destination); MessageConsumer.SetMessageListener (new MessageListener () {public void OnMessage (message de message) {// 7 Créer un message de messagerie textMessage = (TextMessage); Essayez {// 7 Recevoir System.out.println ("Consumer- 1 - Message: [" + TextMessage.gettext () + "]"); {e.printStackTrace ();}}});}}Modèles jms utilisant le ressort
Bien que JMS fournit une interface unifiée pour tous les courtiers de messages, comme JDBC, il peut sembler compliqué lors de la gestion des connexions, des instructions, des ensembles de résultats et des exceptions. Cependant, Spring nous fournit JMSTEMPLAT pour éliminer le code JMS redondant et en double.
Jetons un coup d'œil à l'utilisation de JMstemPlate pour implémenter les files d'attente de messages.
1. Implémentation du code du modèle de file d'attente JMS:
Fichier de configuration:
producteur.xml:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" 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 /> <! - ConnectionFactory fourni par activeMQ -> <Bean Id =" TargetConnectionFactory "> Value = "TCP: // LocalHost: 61616" /> </ Bean> <! - Configurez l'usine de connexion JMS à Spring pour se connecter à la connexion Factory fournie par ActiveMQ -> <Bean Id = "ConnectionFactory"> <propriété Name = " id = "JMstemplate"> <propriété name = "ConnectionFactory" ref = "ConnectionFactory" /> </EAND> <! - Configurez le nom de la destination de file d'attente -> <bean id = "QueueStination"> <Constructor-arg Value = "Direue-Spring-Name" /> </ Bean> <! - Configurer le nom de la destination de la file Value = "Topic-Spring-Name" /> </EAN> <Bean Id = "ProducerserviceImpl" /> </bans>
Consumer.xml:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" 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 /> <! - ConnectionFactory fourni par activeMQ -> <Bean Id =" TargetConnectionFactory "> Value = "TCP: // LocalHost: 61616" /> </ Bean> <! - Configurez l'usine de connexion JMS à Spring pour se connecter à la connexion Factory fournie par ActiveMQ -> <Bean Id = "ConnectionFactory"> <propriété Name = " id = "QueueStintination"> <Constructor-Arg Value = "Queue-Spring-Name" /> </anEn> <! - Configurez l'écouteur de messages -> <bean id = "ConsumerMésageListener" /> <! - Configurez le nom de la destination de la file d'attente -> <bean id = "JMSContainer"> <propriété name = "Destination" ref = "quereueStination" /> <woftwayfa Ref = "ConnectionFactory" /> <propriété name = "MessageListener" ref = "ConsumerMSageListener" /> </anEn> <! - Configurez le nom de la destination de file d'attente -> <bean id = "topicDestination"> <constructor-arg value = "topic-spring-name" /> </ank> </ebrys>
Producteur:
(1) Écrivez d'abord une interface:
Package com.wgs.jms.producer; / ** * Créé par Genshenwang.Nomico le 2017/10/20. * / interface publique activeMQProducerservice {void sendMessage (message final de chaîne);}(2) Implémentation de l'interface:
Package com.wgs.jms.producer; import org.springframework.beans.factory.annotation.autowired; import org.springframework.jms.core.jmstemplate; import org.springframework.jms.core.messageCreator; import javax.annotation.resource; import javax.jms. Genshenwang.Nomico le 2017/10/20. * / classe publique activeMQProducerserviceImplt implémente activeMQproducerservice {@Autowired jmstemlate jmstemlate; @resource (name = "queueStination") Destination Destination; public void sendMessage (Message final de chaîne) {jmstemlate.send (Destination, New MessageCreator () {Message Public CreateMessage (Session Session) Throw textMessage = session.CreateTextMessage (message); return textMessage;}}); System.out.println ("Producer- 1 -Send Message avec succès:" + message);}}(3) Test:
package com.wgs.jms.producer; import org.springframework.context.support.classpathxmlapplicationcontext; / ** * créé par Genshenwang.Nomico le 2017/10/20. * / public class activemqproducermain {public static void main (string [] args) {classpathxmlapplicationContext context = new ClassPathXmlApplicationContex {service.sendMessage ("test" + i);} context.close ();}} consommateur:
(1) Créer un auditeur de messages:
package com.wgs.jms.consumer; import javax.jms.jmsexception; import javax.jms.mesage; import javax.jms.messageListener; import javax.jms.textmesage; / ** * créé par genshenwang.nomicoo le 2017/10/20. * / classe publique ConsumerMessageListener implémente MessageListener {public void OnMessage (message de message) {try {textMessage textMessage = (textMessage); System.out.println ("Consumer-1 -receive Message:" + TextMessage.getText ());}}(2) Test:
package com.wgs.jms.consumer; import org.springframework.context.support.classpathxmlapplicationcontext; / ** * créé par genshenwang.noomico le 2017/10/20. * / public class activemqconsumerMain {public static void main (string [] args) {classpathxmlapplicationContext context = new ClassPathxmlApplicationContext ("Consumer.xml");}}2. Implémentation du code du modèle de sujet JMS:
Changez simplement la question de la file d'attente qui apparaît dans le code ci-dessus en topiedesttination.
Résumer
Ce qui précède est tout le contenu de cet article sur l'introduction de JMS et le code réel d'ActiveMQ. J'espère que ce sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!