1. Comunicação assíncrona
O RMI, o Hessiano e outras tecnologias com as quais entramos em contato antes são todos mecanismos de comunicação síncrona. Quando o cliente chama um método remoto, o cliente deve esperar até que o método remoto seja concluído antes de continuar a executar. O cliente será bloqueado durante esse período (isso causa uma experiência muito ruim para o usuário).
(Comunicação síncrona)
A comunicação síncrona não é a única maneira de interagir entre os programas. No mecanismo de comunicação assíncrono, o cliente não precisa esperar que o serviço processe a mensagem, pode continuar a executar e finalmente receber e processar a mensagem.
(Comunicação assíncrona)
Vantagens da comunicação assíncrona
Não há necessidade de esperar. O cliente só precisa enviar a mensagem para o corretor da mensagem e pode continuar executando outras tarefas sem esperar e tem certeza de que a mensagem será entregue ao destino correspondente.
Orientada a mensagens e desacoplamento. O cliente não precisa se preocupar com as especificações da interface do serviço remoto, ele só precisa colocar a mensagem na fila de mensagens e obter os resultados.
2. Jms
1. Introdução
Antes de surgir o JMS, cada corretor de mensagens tinha uma implementação diferente, o que dificultou o código de mensagem entre diferentes corretores. JMS (Java Message Service) é um padrão que define uma API comum que usa corretores de mensagens. Ou seja, todas as implementações que cumprem as especificações usam uma interface comum, semelhante ao JDBC, fornecendo uma interface comum para operações de banco de dados.
Vários elementos importantes do JMS:
Destino: o canal para o qual a mensagem é enviada do remetente.
ConnectionFactory: Connection Factory, usado para criar objetos conectados.
Conexão: Interface de conexão, usada para criar sessão.
Sessão: interface da sessão, usada para criar o remetente, o destinatário da mensagem e o próprio objeto de mensagem.
MessageConsumer: o consumidor da mensagem.
MessageProducer: o produtor da mensagem.
XxxMessage: Vários tipos de objetos de mensagem, incluindo 5 tipos: bytemessage, mapMessage, objectMessage, streammessage e textMessage.
2. Modelo de mensagem JMS
Diferentes sistemas de mensagens têm diferentes modelos de mensagens. O JMS fornece dois modelos: fila (ponto a ponto) e tópico (publicar/assinar).
Modelo JMS na fila (ponto a ponto)
Em um modelo ponto a ponto, o produtor de mensagens produz uma mensagem e a envia para a fila, e o consumidor da mensagem o tira da fila e consome a mensagem, mas não pode ser consumido repetidamente.
Como mostrado na imagem:
O remetente 1, o remetente 2 e o remetente 3 enviam uma mensagem para o servidor;
As mensagens 1, 2 e 3 formarão uma fila em ordem, e as mensagens na fila não sabem qual destinatário será consumido;
Os receptores 1, 2 e 3 buscam uma mensagem da fila para consumo. Cada vez que uma mensagem é buscada, a fila excluirá a mensagem, o que garante que a mensagem não seja consumida repetidamente.
O modelo de fila JMS também se tornou um modelo P2P (ponto a ponto).
Modelo JMS Topic (publicar/assinar)
A maior diferença entre o modelo de tópico JMS e o modelo de fila JMS está na parte da mensagem que recebe. O modelo de tópico é semelhante a uma conta oficial do WeChat. Os destinatários que se inscrevem na conta oficial podem receber mensagens enviadas pela conta oficial.
Como mostrado na imagem:
Editores 1, 2, 3 publique 3 tópicos 1, 2, 3, respectivamente;
Dessa forma, o grupo de usuários que assina o Tópico 1: assinantes 1, 2, 3 pode receber mensagens do tópico 1; Da mesma forma, os assinantes 4, 5, 6 podem receber mensagens do tópico 2 e os assinantes 7, 8, 9 podem receber mensagens do tópico 3.
O modelo de tópico JMS também se tornou o modelo pus/sub.
Comparação de cada elemento nos dois modos:
3. Modelo de programação JMS tradicional
Produtor:
(1) Crie uma conexão Connection ConnectionFactory;
(2) criar uma conexão usando a fábrica de conexão;
(3) iniciar a conexão;
(4) criar uma sessão;
(5) Crie o destino para envio de mensagens;
(6) criar um produtor;
(7) criar tipo de mensagem e conteúdo de mensagem;
(8) Envie uma mensagem;
Consumidor:
(1) Crie uma conexão Connection ConnectionFactory;
(2) criar uma conexão usando a fábrica de conexão;
(3) iniciar a conexão;
(4) criar uma sessão;
(5) Crie o destino para envio de mensagens;
(6) Crie um consumidor (7) Crie um tipo de mensagem;
(8) receber mensagens;
3. Introdução ao ActiveMQ
O ActiveMQ é o barramento de mensagens de código aberto mais popular e poderoso produzido pelo Apache. O ActiveMQ é uma implementação do provedor JMS que suporta totalmente as especificações JMS1.1 e J2EE 1.4. Embora a especificação JMS tenha sido introduzida há muito tempo, o JMS ainda desempenha uma posição especial entre os aplicativos J2EE de hoje.
Principais recursos do ActiveMQ:
Escrever clientes em vários idiomas e protocolos. Idiomas: Java, C, C ++, C#, Ruby, Perl, Python, Php. Protocolo de aplicativo:
OpenWire, Stomp Rest, WS Notification, XMPP, AMQP
Suporte totalmente para as especificações JMS1.1 e J2EE 1.4 (persistência, mensagens XA, transações)
Para suporte à mola, o ActiveMQ pode ser facilmente incorporado ao sistema usando o Spring e também suporta recursos do Spring 2.0. Passou no teste de servidores J2EE comuns (como Geronimo, JBoss 4, Glassfish, WebLogic). Através da configuração dos adaptadores de recursos JCA 1.5, o ActiveMQ pode ser implantado automaticamente em qualquer servidor comercial J2EE 1.4 compatível e suporta vários protocolos de transmissão: in-vm, tcp, ssl, nio, udp, jgroups, jxta
Suporta persistência de mensagem de alta velocidade através do JDBC e Journal, que garante agrupamentos de alto desempenho, cliente-servidor e suporte ponto a ponto para Ajax
Apoie a integração com o Axis para chamar facilmente o provedor JMS incorporado para testar
4. ActiveMq Combat real
Vamos dar uma olhada em como o ActiveMQ implementa uma fila de mensagens simples.
Modelo de Programação JMS tradicional
1. Implementação do código do modelo da fila JMS:
Produtor:
pacote com.wgs.mq.queue; importar org.apache.activemq.activemqConnectionFactory; importar javax.jms.*;/*** criado por genshenwang.nomico em 2017/10/10/19. */public class Class ActiveMqProducer {private estático final String url = "tcp: // localhost: 61616"; private static final string fileue_name = "file-name"; public static void main (string [] args) throws jmsexception {// 1 Create uma conexão de conexão de conexão de conexão (] args) Crie uma conexão usando uma conexão de conexão de fábrica de conexão = ConnectionFactory.CreateConnection (); // 3 Inicie a conexão Connection.Start (); // 4 Crie uma sessão session Session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Crie um destino para enviar um destino de destino = um session.recretQueUtEue (queue_name); session.CreateProducer (Destination); // 7 Crie mensagens textMessage textMessage = session.createTextMessage (); para (int i = 1; i <= 100; i ++) {// 8 Crie mensagem de conteúdo textMessage.settext ("remessa de 1 -1 -send:"+i); // 9 Envie messageProducer.send (textMessage);} System.out.println ("mensagem enviada com sucesso");Conusmer:
pacote com.wgs.mq.queue; importar org.apache.activemq.activemqConnectionFactory; importar javax.jms.*;/*** criado por genshenwang.nomico em 2017/10/10/19. */public class Class ActiveMqConsumer {private estático final String url = "tcp: // localhost: 61616"; private static final string fileue_name = "file-name"; public static void main (string [] args) throws jmsexception {// 1 criação de conexão de conexão de conexão com conexão com conexão com conextptionCongneationConnENSCENCTONCONNECTIONCONNECTION; Crie uma conexão usando uma conexão de conexão conexão de fábrica = ConnectionFactory.CreateConnection (); // 3 Inicie a conexão Connection.Start (); // 4 Crie uma sessão session Session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Crie um destino para enviar um destino de destino = sessão. session.createConsumer (destino); messageConsumer.SetMessAGelistener (new Messagelistener () {public void onMessage (mensagem da mensagem) {// 7 Crie mensagem textMessage textMessage = (textMessage) mensagem; tente {// 7 Receber mensagem System.out.println ("Consumer- 1 - Receber mensagem: [" + textMa. {E.PrintStackTrace ();}}});}}2. Implementação do código do modelo de tópico JMS:
Produtor:
pacote com.wgs.mq.topic; importar org.apache.activemq.activemqConnectionFactory; importar javax.jms.*;/*** publicar modo de assinatura* criado por genshenwang.nomico em 2017/10/19. */public class Class ActiveMQProducer {private estático final String url = "tcp: // localhost: 61616"; private static final string tópica_name = "tópico-name"; public static void main (string [] args) lança jmsexception {// 1 Crie uma conexão de fábrica de conexão () conexão de conexão de fábrica de conexão = conexão de conexão.CreateConnection (); // 3 Inicie a conexão Connection.start (); // 4 Crie uma sessão de sessão = Connection.CreateSession (false, session.auto_acknowledge); // Crie um destino para enviar mensagens com o tópico Destino de destino. session.CreateProducer (Destination); // 7 Crie uma mensagem textMessage textMessage = session.createTextMessage (); para (int i = 1; i <= 100; i ++) {// 8 Crie mensagem de conteúdo textMessage.settext ("remessa de 1 -1 -send:"+i); // 9 Envie messageProducer.send (textMessage);} System.out.println ("mensagem enviada com sucesso");Consumidor:
pacote com.wgs.mq.topic; importar org.apache.activemq.activemqConnectionFactory; importar javax.jms.*;/*** publicar modo de assinatura* criado por genshenwang.nomico em 2017/10/19. */public classe ActiveMqConsumer {private estático final String url = "tcp: // localhost: 61616"; private estático final string tópica_name = "tópico-name"; public static void main (string [] args) lança jmsexception (// 1 criar uma conexão de conexão de conexão (] fábrica de fábrica uma conexão de conexão de fábrica de conexão = ConnectionFactory.CreateConnection (); // 3 Inicie a conexão.Start (); // 4 Crie uma sessão session = Connection.CreateSession (false, session.auto_acknowledge); // 5 Crie o destino para enviar o messaging de destino = session.CreatOnser (Topation_Name); session.createConsumer (destino); messageConsumer.setMessaGelistener (new Messagelistener () {public void onMessage (mensagem de mensagem) {// 7 Crie uma mensagem textMessage textMessage = (textMessage) mensagem; tente {// 7 Receber mensagem System.out.println ("Consumer- 1 - Receber: [" + textM); {E.PrintStackTrace ();}}});}}Modelos jms usando a primavera
Embora o JMS forneça uma interface unificada para todos os corretores de mensagens, como o JDBC, ele pode parecer complicado ao lidar com conexões, declarações, conjuntos de resultados e exceções. No entanto, a Spring nos fornece o JMSplate para eliminar o código JMS redundante e duplicado.
Vamos dar uma olhada em como usar o Jmstemplate para implementar filas de mensagens.
1. Implementação do código do modelo da fila JMS:
Arquivo de configuração:
produtor.xml:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 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 "> <Contextation-config/> <! name = "brokerurl" value = "tcp: // localhost: 61616"/> </bean> <!-Configure a fábrica de conexão JMS na mola para conectar-se ao conexão fornecida fornecida por ActiveMQ-> <bean id = "ConnectionFactory"> <namesconnection-Tonectório "-" TargetConnection = " <bean id = "jmstemplate"> <propriedade name = "ConnectionFactory" ref = "ConnectionFactory"/> </bean> <!-Configure o nome do destino da fila-> <bean id = "fileuEdestination"> <construtor-arg value = fileee-spring-name "/> </bean> <! <Construtor-arg value = "tópico-spring-name"/> </ Bean> <bean id = "prodserServiceImpl"/> </beans>
consumer.xml:
<? xml versão = "1.0" coding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http:/wwww.w3 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 "> <Contextation-config/> <! name = "brokerurl" value = "tcp: // localhost: 61616"/> </bean> <!-Configure a fábrica de conexão JMS na mola para se conectar à conexão fornecida fornecida por ActiveMq-> <bean id = "ConnectionFactory"> <nome da propriedade "segmentconnectório"-"TargetConnection =" <bean id = "fileuedestination"> <construtor-arg value = "fileeue-spring-name"/> </bean> <!-Configure o ouvinte da mensagem-> <bean id = "ConsumerMessaGelistener"/> <!-Configure o nome da fila de destino-> <bean id = "jMsCainner" name = "ConnectionFactory" ref = "ConnectionFactory"/> <Propriedade name = "Messagelistener" ref = "ConsumerMesSaGEListener"/> </i Bean> <!-Configure o nome do destino da fila-> <bean id = "tópico Destinação"> <construtor-arg = "tópico-spring-name"/>
Produtor:
(1) Escreva uma interface primeiro:
pacote com.wgs.jms.producer;/*** Criado por genshenwang.nomico em 2017/10/20. */interface pública ActiveMqProdUcerService {void sendMessage (mensagem final da string);}(2) Implementação de interface:
pacote com.wgs.jms.produces; importar org.springframework.beans.factory.annotation.autowired; importar org.springframework.jms.core.jmstemplate; importmsrg.springframework.jms.core.messagEcreator; importms Javax.AnTax.AnTranstation.jm.core.messagecReator; importms.annotrax.inotratation.notratation.jms.core.messageRagor; Genshenwang.nomico em 2017/10/20. */public class ActiveMQProducerServiceImpl implements ActiveMQProducerService {@Autowired JmsTemplate jmsTemplate;@Resource(name = "queueDestination") Destination destination;public void sendMessage(final String message) {jmsTemplate.send(destination, new MessageCreator() {public Message createMessage(Session session) throws JMSException {TextMessage textMessage = session.createTextMessage (message); retorna textMessage;}}); system.out.println ("produtor- 1 -send mensagem com sucesso:" + mensagem);}}(3) Teste:
pacote com.wgs.jms.producer; importar org.springframework.context.support.classpathxmlapplicationContext;/*** Criado por genshenwang.nomico em 2017/10/20. */public class Class ActiveMqProducerMain {public static void main (string [] args) {ClassPathXMLApplicationContext context = new ClassPathXMLApplicationContext ("Produner.xml"); ActiveMQProducerService Service = context.getBean (ActiveMQProducserS; {service.sendMessage ("test" + i);} context.close ();}} consumidor:
(1) Crie um ouvinte de mensagem:
pacote com.wgs.jms.consumer; importar javax.jms.jmsexception; importar javax.jms.message; importar javax.jms.messageListener; importar javax.jms.textmessage; */public classe ConsumermesSaGelistener implementa Messagelistener {public void onMessage (mensagem da mensagem) {tente {textMessage textMessage = (textMessage) message; System.out.println ("Consumer -1 -Receive message: + textMessage.getText ();} Catch (jmException;(2) Teste:
pacote com.wgs.jms.consumer; importar org.springframework.context.support.classpathxmlapplicationcontext;/*** criado por genshenwang.nomico em 2017/10/20. */public classe ActiveMqConsumermain {public static void main (string [] args) {ClassPathXMLApplicationContext context = new ClassPathXMLApplicationContext ("Consumer.xml");}}}2. Implementação do código do modelo de tópico JMS:
Basta alterar a estaca na fila que aparece no código acima para o TopicDestination.
Resumir
O exposto acima é todo o conteúdo deste artigo sobre a introdução do JMS e o código real do ActiveMQ. Espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!