JMS中点对点消息

来源:互联网 发布:淘宝刷单任务平台源码 编辑:程序博客网 时间:2024/05/21 23:43

 点对点消息传送模型允许JMS客户端通过队列(Queue)这个虚拟通道来同步和异步发送、接收消息。消息的生产者成为QueueSender,消费者为QueueReceiver。点对点模型是一个基于拉取(pull,即receive方式)或者基于轮询(polling,即异步接收)的消息传输模型,这种模型从队列中请求消息,而不是JMS Provider将消息自动的推送给客户端。发送到队列的任何一条消息,将会被一个而且仅仅一个消费者接收,即使有多个消费者侦听同一个队列。

    点对点消息传送模型,即支持异步“即发即弃”,又支持同步的“请求--应答”的消息发送方式。(稍后代码实例)

    点对点模型支持负载均衡,即多个消息消费者侦听同一个队列时,JMS Provider负责将这些消息以"某种策略"均衡的分发给它们.事实上点对点模型的负载均衡很容易实现,因为消息消费者只有处于"空闲时"才会向JMS Provider"索取"消息.对于Queue,还提供了使用Browser的方式查看队列消息而不消费它们.

    点对点消息模型,对于JMS Provider而言,就是一个队列,JMS Provider将会对消息按照其发送到队列的顺序排序.然后依次发送给消费者(权重优先),一旦消息被消费者接收(确认),消息将会从队列中移除.

    不过需要特殊强调一点:JMS Prodiver并不是严格的保证队列中消息移除的顺序,特别是在多个消费者Client时;当多个消费者同时侦听消息队列,JMS Prodiver将会把队列中的消息,依次转发给各个Client,此时如果消息被接收且确认,消息将会从队列中移除,此消息有可能并不是队列的第一个元素;当一个消息未能确认时,JMS Provider会将此消息不断的重发,直到重发次数达到阀值;一条消息不能正确接收,这种情况不会影响到队列中其他消息的正常消费;而且由于网络的问题,优先发送的消息,可能在消费者接收的时间上滞后.由此可见,依靠Queue来完全实现消息的队列化消费是错误的.(理想的情况是,一个消息接收确认之后,队列中此后的消息才会被发送给消费者).

    你可以简单的认为P2P消息模型的存储机制为:

Java代码  收藏代码
  1. +++++++++++++++  
  2. ++MessageId   |    Created               |    Priority++  
  3. ++100                 100000000000               3  
  4. ++101                 100000002000               3  
  5. ++102                 100000004000               2  

    对于消息的发送顺序为"order by priority des,created asc",一旦发送成功,将会delete.

 

    点对点消息传送模型有两种:

    1) 即发即弃: 一种异步的消息发送和确认机制,Producer发送消息之后,它无需等待此消息被消费的"响应".

    2) 请求-应答: 一种同步机制,Producer发送消息之后,它阻塞,直到此消息被消费;当消息被消费时,将会向一个"响应队列"中发送一个"通知",那么对于Producer而言,就是接收到这个"通知后"才会返回.

Java代码  收藏代码
  1. ###contextFactory  
  2. java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory  
  3. ###brokerUrl,any protocol  
  4. java.naming.provider.url = tcp://localhost:61616  
  5. ##username  
  6. ##java.naming.security.principal=  
  7. ##password  
  8. ##java.naming.security.credentials=  
  9. ##connectionFactory,for building sessions  
  10. connectionFactoryNames = QueueCF,TopicCF  
  11. ##topic.<topicName> = <physicalName-of-topic>  
  12. ##your application should use <topicName>,such as:  
  13. ## context.lookup("topic1");  
  14. ##It can be more than once  
  15. topic.topic1 = jms.topic1  
  16. ##queue.<topicName> = <physicalName-of-queue>  
  17. queue.queue1 = jms.queue1  

 

Java代码  收藏代码
  1. ///请求应答模式:生产者  
  2. package com.test.jms.simple;  
  3.   
  4. import javax.jms.Connection;  
  5. import javax.jms.ConnectionFactory;  
  6. import javax.jms.DeliveryMode;  
  7. import javax.jms.Destination;  
  8. import javax.jms.Message;  
  9. import javax.jms.MessageConsumer;  
  10. import javax.jms.MessageProducer;  
  11. import javax.jms.Queue;  
  12. import javax.jms.QueueConnectionFactory;  
  13. import javax.jms.QueueReceiver;  
  14. import javax.jms.Session;  
  15. import javax.naming.Context;  
  16. import javax.naming.InitialContext;  
  17.   
  18. public class SimpleProductor {  
  19.   
  20.     private MessageProducer producer;  
  21.     private Session session;  
  22.     private Connection connection;  
  23.     private boolean isOpen = true;  
  24.     private Destination replyTo;  
  25.       
  26.     public SimpleProductor() throws Exception{  
  27.         Context context = new InitialContext();  
  28.         ConnectionFactory connectionFactory = (QueueConnectionFactory)context.lookup("QueueCF");  
  29.         connection = connectionFactory.createConnection();  
  30.         session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  
  31.         Destination queue = (Queue)context.lookup("queue1");  
  32.         replyTo = (Queue)context.lookup("test-repyto");  
  33.         producer = session.createProducer(queue);  
  34.         producer.setDeliveryMode(DeliveryMode.PERSISTENT);  
  35.         connection.start();  
  36.           
  37.     }  
  38.       
  39.       
  40.     public boolean send(String text) {  
  41.         if(!isOpen){  
  42.             throw new RuntimeException("session has been closed!");  
  43.         }  
  44.         try{  
  45.             Message message = session.createTextMessage(text);  
  46.             String cid = "ID:" + System.currentTimeMillis();  
  47.             message.setJMSCorrelationID(cid);  
  48.             producer.send(message);  
  49.             MessageConsumer consumer = session.createConsumer(replyTo,"JMSCorrelationID='" + cid + "'");  
  50.             //最多重发5次  
  51.             for(int i=0;i< 5;i++){  
  52.                 Message replyMessage = consumer.receive(30000);  
  53.                 if(replyMessage != null){  
  54.                     System.out.println("Reply success:" + replyMessage.getJMSCorrelationID());  
  55.                     break;  
  56.                 }  
  57.             }  
  58.             consumer.close();  
  59.             return true;  
  60.         }catch(Exception e){  
  61.             return false;  
  62.         }  
  63.     }  
  64.       
  65.     public synchronized void close(){  
  66.         try{  
  67.             if(isOpen){  
  68.                 isOpen = false;  
  69.             }  
  70.             session.close();  
  71.             connection.close();  
  72.         }catch (Exception e) {  
  73.             //  
  74.         }  
  75.     }  
  76.       
  77. }  

 

Java代码  收藏代码
  1. //请求应答模式:消费者  
  2. package com.test.jms.simple;  
  3.   
  4. import javax.jms.Connection;  
  5. import javax.jms.ConnectionFactory;  
  6. import javax.jms.Destination;  
  7. import javax.jms.MessageConsumer;  
  8. import javax.jms.Queue;  
  9. import javax.jms.QueueConnectionFactory;  
  10. import javax.jms.Session;  
  11. import javax.naming.Context;  
  12. import javax.naming.InitialContext;  
  13.   
  14. import com.test.jms.object.QueueMessageListener;  
  15.   
  16. public class SimpleConsumer {  
  17.   
  18.     private Connection connection;  
  19.     private Session session;  
  20.     private MessageConsumer consumer;  
  21.       
  22.     private boolean isStarted;  
  23.       
  24.     public SimpleConsumer() throws Exception{  
  25.         Context context = new InitialContext();  
  26.         ConnectionFactory connectionFactory = (QueueConnectionFactory)context.lookup("QueueCF");  
  27.         connection = connectionFactory.createConnection();  
  28.         session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  
  29.         Destination queue = (Queue)context.lookup("queue1");  
  30.         consumer = session.createConsumer(queue);  
  31.         consumer.setMessageListener(new QueueMessageListener(session));  
  32.         connection.start();  
  33.     }  
  34.       
  35.       
  36.     public synchronized boolean start(){  
  37.         if(isStarted){  
  38.             return true;  
  39.         }  
  40.         try{  
  41.             connection.start();  
  42.             isStarted = true;  
  43.             return true;  
  44.         }catch(Exception e){  
  45.             return false;  
  46.         }  
  47.     }  
  48.       
  49.     public synchronized void close(){  
  50.         isStarted = false;  
  51.         try{  
  52.             session.close();  
  53.             connection.close();  
  54.         }catch(Exception e){  
  55.             //  
  56.         }  
  57.     }  
  58. }  

 

Java代码  收藏代码
  1. ///请求应答模式:消息侦听器  
  2. package com.test.jms.object;  
  3.   
  4. import javax.jms.DeliveryMode;  
  5. import javax.jms.Destination;  
  6. import javax.jms.Message;  
  7. import javax.jms.MessageListener;  
  8. import javax.jms.MessageProducer;  
  9. import javax.jms.Session;  
  10. import javax.jms.TextMessage;  
  11.   
  12. public class QueueMessageListener implements MessageListener{  
  13.   
  14.     private Session session;  
  15.     public QueueMessageListener(Session session){  
  16.         this.session = session;  
  17.     }  
  18.     public void onMessage(Message message) {  
  19.         if(message == null){  
  20.             return;  
  21.         }  
  22.         try{  
  23.             Destination replyTo = message.getJMSReplyTo();  
  24.             if(message instanceof TextMessage){  
  25.                 String text = ((TextMessage)message).getText();  
  26.                 System.out.println(text);  
  27.             }  
  28.             if(replyTo != null){  
  29.                 message.clearBody();  
  30.                 MessageProducer producer = session.createProducer(replyTo);  
  31.                 producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  
  32.                 producer.setTimeToLive(50000);  
  33.                 producer.send(message);  
  34.                 producer.close();  
  35.             }  
  36.               
  37.         }catch(Exception e){  
  38.             e.printStackTrace();  
  39.         }  
  40.     }  
  41. }  

 

0 0
原创粉丝点击