1. Comunicación asincrónica
Las tecnologías RMI, Hesse y otras con las que hemos entrado antes son mecanismos de comunicación sincrónicos. Cuando el cliente llama a un método remoto, el cliente debe esperar hasta que se complete el método remoto antes de continuar ejecutándose. El cliente será bloqueado durante este período (esto causa una experiencia de usuario muy mala).
(Comunicación sincrónica)
La comunicación sincrónica no es la única forma de interactuar entre los programas. En el mecanismo de comunicación asincrónica, el cliente no necesita esperar a que el servicio procese el mensaje, puede continuar ejecutándose y finalmente recibiendo y procesando el mensaje.
(Comunicación asíncrona)
Ventajas de la comunicación asincrónica
No es necesario esperar. El cliente solo necesita enviar el mensaje al corredor de mensajes, y puede continuar realizando otras tareas sin esperar, y está seguro de que el mensaje se entregará al destino correspondiente.
Orientado a mensajes y desacoplamiento. El cliente no necesita preocuparse por las especificaciones de la interfaz del servicio remoto, solo necesita poner el mensaje en la cola de mensajes y obtener los resultados.
2. JMS
1. Introducción
Antes de que surgiera JMS, cada corredor de mensajes tenía una implementación diferente, lo que hacía que el código de mensaje entre los diferentes corredores fuera difícil de ser universal. JMS (Java Message Service) es un estándar que define una API común que utiliza corredores de mensajes. Es decir, todas las implementaciones que cumplen con las especificaciones utilizan una interfaz común, similar a JDBC que proporciona una interfaz común para las operaciones de la base de datos.
Varios elementos importantes de JMS:
Destino: el canal al que se envía el mensaje desde el remitente.
ConnectionFactory: Connection Factory, utilizado para crear objetos conectados.
Conexión: interfaz de conexión, utilizada para crear sesión.
Sesión: interfaz de sesión, utilizado para crear el remitente, el destinatario del mensaje y el objeto de mensaje en sí.
MessageConsumer: el consumidor del mensaje.
MessageProducer: el productor del mensaje.
XXXMessage: varios tipos de objetos de mensaje, incluidos 5 tipos: byleMessage, MapMessage, ObjectMessage, StreamMessage y TextMessage.
2. Modelo de mensajes JMS
Diferentes sistemas de mensajes tienen diferentes modelos de mensajes. JMS proporciona dos modelos: cola (punto a punto) y tema (publicar/suscribirse).
Modelo JMS Queue (punto a punto)
En un modelo de igual a igual, el productor de mensajes produce un mensaje y lo envía a la cola, y el consumidor de mensajes lo saca de la cola y consume el mensaje, pero no se puede consumir repetidamente.
Como se muestra en la imagen:
Remitente 1, remitente 2 y remitente 3 Envía un mensaje al servidor;
Los mensajes 1, 2 y 3 formarán una cola en orden, y los mensajes en la cola no saben por qué destinatario será consumido;
Los receptores 1, 2 y 3 respectivamente obtienen un mensaje de la cola para el consumo. Cada vez que se obtiene un mensaje, la cola eliminará el mensaje, lo que asegura que el mensaje no se consumirá repetidamente.
El modelo de cola JMS también se ha convertido en un modelo P2P (punto a punto).
Modelo de JMS Topic (Publicar/Suscripción)
La mayor diferencia entre el modelo de tema JMS y el modelo de cola JMS se encuentra en la parte de la recepción del mensaje. El modelo de tema es similar a una cuenta oficial de WeChat. Los destinatarios que se suscriben a la cuenta oficial pueden recibir mensajes presionados por la cuenta oficial.
Como se muestra en la imagen:
Publishers 1, 2, 3 Publicar 3 temas 1, 2, 3 respectivamente;
De esta manera, el grupo de usuarios que se suscribe al Tema 1: los suscriptores 1, 2, 3 pueden recibir mensajes del Tema 1; Del mismo modo, los suscriptores 4, 5, 6 pueden recibir mensajes del Tema 2, y los suscriptores 7, 8, 9 pueden recibir mensajes del Tema 3.
El modelo de tema JMS también se ha convertido en el modelo PUS/sub.
Comparación de cada elemento en los dos modos:
3. Modelo tradicional de programación JMS
Productor:
(1) Crear una conexión de fábrica ConnectionFactory;
(2) crear una conexión usando la fábrica de conexión;
(3) iniciar la conexión;
(4) crear una sesión;
(5) Cree el destino para enviar mensajes;
(6) crear un productor;
(7) Crear tipo de mensaje y contenido de mensaje;
(8) enviar un mensaje;
Consumidor:
(1) Crear una conexión de fábrica ConnectionFactory;
(2) crear una conexión usando la fábrica de conexión;
(3) iniciar la conexión;
(4) crear una sesión;
(5) Cree el destino para enviar mensajes;
(6) crear un consumidor (7) crear un tipo de mensaje;
(8) recibir mensajes;
3. Introducción a ActivemQ
ActivemQ es el bus de mensajes de código abierto más popular y potente producido por Apache. ActivEMQ es una implementación de proveedores de JMS que admite completamente las especificaciones JMS1.1 y J2EE 1.4. Aunque la especificación de JMS se ha introducido durante mucho tiempo, JMS todavía juega una posición especial entre las aplicaciones J2EE de hoy.
Características principales de ActivemQ:
Escribir clientes en múltiples idiomas y protocolos. Idiomas: Java, C, C ++, C#, Ruby, Perl, Python, Php. Protocolo de aplicación:
OpenWire, Stomp Rest, Notificación de WS, XMPP, AMQP
Soporte totalmente para JMS1.1 y J2EE 1.4 Especificaciones (persistencia, mensajes XA, transacciones)
Para el soporte de primavera, ActivemQ se puede incrustar fácilmente en el sistema usando Spring, y también admite las características de Spring 2.0. Pasó la prueba de servidores J2EE comunes (como Geronimo, JBoss 4, Glassfish, WebLogic). A través de la configuración de los adaptadores de recursos JCA 1.5, ActiveMQ se puede implementar automáticamente en cualquier servidor comercial J2EE 1.4 compatible y admite múltiples protocolos de transmisión: In-VM, TCP, SSL, NIO, UDP, JGroups, JXTA
Admite persistencia de mensajes de alta velocidad a través de JDBC y Journal, que garantiza grupos de alto rendimiento, servidor cliente y soporte punto a punto para AJAX
Apoye la integración con el eje para llamar fácilmente al proveedor de JMS integrado para realizar pruebas
4. Activemq Combat Real
Echemos un vistazo a cómo ActivemQ implementa una cola de mensajes simple.
Modelo de programación JMS tradicional
1. Implementación del código del modelo de cola JMS:
Productor:
paquete com.wgs.mq.queue; importar org.apache.activemq.activemqconnectionFactory; import javax.jms.*;/*** creado por genshenwang.nomico el 2017/10/19. */public class ActivEMQProDucer {private static final String url = "tcp: // localhost: 61616"; private static final string queue_name = "Queue-name"; public static void main (string []) lanza jmsexception {// 1 creación de una conexión de conexión factory factinory = newActatemCaMqconnection; Cree una conexión utilizando una conexión de fábrica de conexión = ConnectionFactory.CreateConnection (); // 3 Inicie la conexión Connection.start (); // 4 Cree una sesión Session Session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Cree un destino para enviar un destino de destino = session.Createqueue (QUEE_NAME); // 6 CREATE A PRODUCTOR A PRODUCTOR A PRODUCTOR A PRODUCTOR session.CreateProDucer (destino); // 7 Crear mensaje TextMessage TextMessage = Session.CreateTextMessage (); for (int i = 1; i <= 100; i ++) {// 8 Crear contenido de mensaje TextMessage.setText ("Sender- 1 -send Mensaje:"+I); // 9 Enviar mensaje MessageProDucer.send (TextMessage);} System.Println ("Mensaje enviado con éxito"); Session.Close (Connection.Clase ();}}}}Conusmer:
paquete com.wgs.mq.queue; importar org.apache.activemq.activemqconnectionFactory; import javax.jms.*;/*** creado por genshenwang.nomico el 2017/10/19. */public class activemqConsumer {private static final string url = "tcp: // localhost: 61616"; private static final string queue_name = "Queue-name"; public static void main (string []) lanza jmsexception {// 1 creación de una conexión de conexión factory factinory = newActatemqonnection; Cree una conexión utilizando una conexión de fábrica Connection = ConnectionFactory.CreateConnection (); // 3 Inicie la conexión Connection.start (); // 4 Cree una sesión Session Session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Cree un destino para enviar un destino de mensaje de mensaje = sesion.esscreatequeue (Qee_name); // 6 CREATE A UNSUNTER MENSUMER MENSUMER session.CreateConsumer (destino); MessageConsumer.SetMessageListener (new MessageListener () {public void onMessage (mensaje mensaje) {// 7 cree mensajes textMessage textMessage = (textMessage) Message; inty {// 7 Recibe mensajes System.out.println ("Consumer- 1 - Recibir mensaje: [" + TextMessage.gettext () + "]");} catch (jmSexception E) {E.PrintStackTrace ();}}});}}2. Implementación del código de modelo de tema JMS:
Productor:
paquete com.wgs.mq.topic; import org.apache.activemq.activemqconnectionFactory; import javax.jms.*;/*** Publicar el modo de suscripción* creado por genshenwang.nomico el 2017/10/19. */public class ActivEMQProDucer {private static final String url = "tcp: // localhost: 61616"; private static final string topic_name = "topic-name"; public static void main (string [] lanza jmsexception {// 1 crea una conexión de conexión factoryConnectionFactoryFactory = new ActivemqConnectionnectionnectionnectionnectionnectionnectioner (2 orl); una conexión de fábrica Connection = ConnectionFactory.CreateConnection (); // 3 Inicie la conexión Connection.start (); // 4 Cree una sesión Session Session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Cree un destino para enviar mensajes con destino de destino = session.CreateTopic (topic_name); // 6 Create a productor Message MessagePRODUCER Profesor = Profección de mensajes = session.CreateProDucer (destino); // 7 Cree un mensaje TextMessage TextMessage = session.CreateTextMessage (); for (int i = 1; i <= 100; i ++) {// 8 Crear contenido de mensaje TextMessage.setText ("Sender- 1 -send Mensaje:"+I); // 9 Enviar mensaje MessageProDucer.send (TextMessage);} System.Println ("Mensaje enviado con éxito"); Session.Close (Connection.Clase ();}}}}Consumidor:
paquete com.wgs.mq.topic; import org.apache.activemq.activemqconnectionFactory; import javax.jms.*;/*** Publicar el modo de suscripción* creado por genshenwang.nomico el 2017/10/19. */public class activemqConsumer {private static final string url = "tcp: // localhost: 61616"; private static final string topic_name = "topic-name"; public static void main (string [] lanza jmsexception {// 1 crea una conexión de conexión factoryConnectionFactoryFactory = New Activemqonnectionnectionnectionnectionnectionnectionnectioner (Úrlica; una conexión de fábrica Connection = ConnectionFactory.CreateConnection (); // 3 Inicie Connection.start (); // 4 Cree una sesión Session Session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Cree el destino para enviar el destino de destino = session.CreateTopic (topic_name); // 6 Crear un consumidor Messageconsumer Messumerumer) session.CreateConsumer (destino); MessageConsumer.setMessageListener (new MessageListener () {public void onMessage (mensaje mensaje) {// 7 Cree un mensaje TextMessage TextMessage = (TextMessage) Mensaje; intente {// 7 Recibir Mensaje System.out.println ("Consumer- 1 - Recibir mensaje: [" + TextMessage.gettext () + "]");} (JMSEXCEIPTIONCTACT. {E.PrintStackTrace ();}}});}}Plantillas JMS usando Spring
Aunque JMS proporciona una interfaz unificada para todos los corredores de mensajes, como JDBC, puede parecer complicado al manejar conexiones, declaraciones, conjuntos de resultados y excepciones. Sin embargo, Spring nos proporciona JMSTESTEPLATE para eliminar el código JMS redundante y duplicado.
Echemos un vistazo a cómo usar JMstemPlate para implementar colas de mensajes.
1. Implementación del código del modelo de cola JMS:
Archivo de configuración:
productor.xml:
<? xml versión = "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/scoans/spring-ste http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <context: annotation-config/> <!-Connection proporcionado por activemq-> <bean id =" TargetConnection-factory " value = "tcp: // localhost: 61616"/> </bean> <!-Configure la fábrica de conexión de JMS en Spring para conectarse a la ConnectionFactory proporcionada por ActiveMQ-> <Bean ID = "ConnectionFactory"> <Property Name = "TargetConnectionFactory" ref = "TargetFactory"/> </bean> <! <Property name = "ConnectionFactory" REF = "ConnectionFactory"/> </bean> <!-Configure el nombre del destino de la cola-> <bean id = "queedeSteestination"> <constructor-arg value = "Queue-spring-name"/> </bean> <!-Configure el nombre del destino de la cola-> <bean id = "topicEdestination"> <constructor-arg-arg-arg-arg value = "Topic-Spring-Name"/> </bean> <bean id = "ProducerServiceImpl"/> </beans>
Consumer.xml:
<? xml versión = "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/scoans/spring-ste http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <context: annotation-config/> <!-Connection proporcionado por activemq-> <bean id =" TargetConnection-factory " value = "tcp: // localhost: 61616"/> </bean> <!-Configure la fábrica de conexión de JMS en Spring para conectarse a la conexión ConnectionFactory proporcionada por Activemq-> <bean id = "ConnectionFactory"> <Property Name = "TargetConnectionFactory" ref = "TargetConnectionFactory"/> </bean> <! <constructor-arg value = "queue-spring-name"/> </ bean> <!-Configurar el oyente de mensajes-> <bean id = "consumermessageListener"/> <!-Configurar el nombre de la dintera de Queue-> <bean id = "jmsContainer"> <nombre de propiedad name = "destino" ref = "coleedestination"/> <name de propiedad = "contextatory" Connectatory "refleatory"/"Reffactory"/"Refactory" rehefactory " name = "MessageListener" ref = "ConsumesMessageListener"/> </bean> <!-Configure el nombre del destino de la cola-> <bean id = "topicDestination"> <constructor-arg value = "topic-spring-name"/> </bean> </beans>
Productor:
(1) Escriba una interfaz primero:
paquete com.wgs.jms.producer;/*** Creado por Genshenwang.nomico el 2017/10/20. */Public Interface ActivEMQProducerService {void sendMessage (mensaje de cadena final);}(2) Implementación de la interfaz:
paquete com.wgs.jms.producer; import org.springframework.beans.factory.annotation.aUtowired; import org.springframework.jms.core.jmstemplate; import og.springframework.jms.core.messageCreator; import javax.annotation.resource; import javax.j. Genshenwang.nomico el 2017/10/20. */public class ActivEMQProDucerServiceImpl implements ActivEMQProDucerService {@AUTOWIRED JMSTEMPLATE JMSTEMPLATE; @RESOURCE (name = "QueedeStination") Destino de destino; public void sendMessage (sesionsage de cadena final) {jMstemSpLate.ssend (destino, nuevo mensajería () {TextMessage textMessage = session.CreateTextMessage (mensaje); return textMessage;}}); system.out.println ("Productor- 1 -Send Mensaje con éxito:" + Message);}}(3) Prueba:
paquete com.wgs.jms.producer; import org.springframework.context.support.classpathxmlaPplicationContext;/*** creado por genshenwang.nomico el 2017/10/10/20. */public class ActivEMQProDucermain {public static void main (string [] args) {classpathxmlaPlaPlicationContext context = new ClassPathXMLApPlicationContext ("Producer.xml"); ActiveMqProDuceService Service = context.getBean (ActivEMqProDucerService.class); para (inti i = 0; i <100; i ++) {Service.SendMessage ("Test" + I);} context.close ();}} consumidor:
(1) Cree un oyente de mensajes:
paquete com.wgs.jms.consumer; import javax.jms.jmsexception; import javax.jms.message; import javax.jms.messageListener; import javax.jms.textmessage;/*** creado por genshenwang.nomico en 2017/10/20. */public class ConsumesMessageListener implementa MessageListener {public void onMessage (mensaje mensaje) {try {textMessage textMessage = (textMessage) Message; System.out.println ("Consumer -1 -ReCeive Message:" + TextMessage.getText ());} Catch (JMsexception e) {E.PrintststArtAttAtre ();(2) Prueba:
paquete com.wgs.jms.consumer; import org.springframework.context.support.classpathxmlapplicationContext;/*** creado por genshenwang.nomico el 2017/10/10/20. */public class activemqConsumermain {public static void main (string [] args) {classpathxmlaPlaPlicationContext context = new ClassPathXMLApPlicationContext ("Consumer.xml");}}2. Implementación del código de modelo de tema JMS:
Simplemente cambie la Panada de cola que aparece en el código anterior a TopicDestination.
Resumir
Lo anterior es todo el contenido de este artículo sobre la introducción de JMS y el código real de ActivemQ. Espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!