ActiveMQ实战(二)--ActiveMQ的通信方式之P2P点对点通信(point-to-point)

来源:互联网 发布:java函数重载是指 编辑:程序博客网 时间:2024/05/21 09:59

一、简介


点对点的消息发送方式主要建立在 Message Queue,Sender,receiver上,Message Queue 存贮消息,Sender 发送消息,receive接收消息.具体点就是Sender Client发送Message Queue ,而 receiver Client从Queue中接收消息和"发送消息已接受"到Queue,确认消息接收。消息发送客户端与接收客户端没有时间上的依赖,发送客户端可以在任何时刻发送信息到Queue,而不需要知道接收客户端是不是在运行。




P2P的过程理解起来很简单。它好比是两个人打电话,这两个人是独享这一条通信链路的。一方发送消息,另外一方接收,就这么简单,在P2P里一个queue只有一个发送者和一个接收者。


点对点通信实现有两种方式:


第一种:直接Receive方式
第二种:使用Listener监听方式



二、实现步骤


1.开启ActiveMQ服务
2.创建生产者,用于向指定队列发送测试数据 
3.创建消费者-Receive方式,消费由生产者发送的队列的消息 
4.创建消费者-Listener方式,消费由生产者发送的队列的消息 
5.查看ActiveMQ后台,显示,生产者,消费者及消息的接收和处理状态


三、实战点对点通信


A)直接Receive方式


ActiveMQ消息签收机制:


客戶端成功接收一条消息的标志是一条消息被签收,成功应答。


消息的签收情形分两种:


1、带事务的session
   如果session带有事务,并且事务成功提交,则消息被自动签收。如果事务回滚,则消息会被再次传送。


2、不带事务的session


   不带事务的session的签收方式,取决于session的配置。


ActiveMQ支持一下三种模式:


   Session.AUTO_ACKNOWLEDGE  消息自动签收
   Session.CLIENT_ACKNOWLEDGE  客戶端调用acknowledge方法手动签收
   Session.DUPS_OK_ACKNOWLEDGE 不是必须签收,消息可能会重复发送。在第二次重新传送消息的时候,消息
 

1.Session.AUTO_ACKNOWLEDGE。当客户成功的从receive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。

2.Session.CLIENT_ACKNOWLEDGE。客户通过消息的acknowledge 方法确认消息。需要注意的是,在这种模式中,确认是在会话层上进行:确认一个被消费的消息将自动确认所有已被会话消费的消息。例如,如果一个消息消费者消费了10 个消息,然后确认第5 个消息,那么所有10 个消息都被确认。

3.Session.DUPS_ACKNOWLEDGE。该选择只是会话迟钝第确认消息的提交。如果JMS provider 失败,那么可能会导致一些重复的消息。如果是重复的消息,那么JMS provider 必须把消息头的JMSRedelivered 字段设置为true。



1)生产者

package com.fendo.mq;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.spring.ActiveMQConnectionFactory;/** * 消息生产者 * @author fendo * */public class JMSProducer {private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址private static final int SENDNUM=10;//发送的消息数量public static void main(String[] args) {ConnectionFactory connectionFactory;//连接工厂Connection connection = null; //连接Session session; //会话 接受或者发送消息的线程Destination destination;//消息的目的地MessageProducer messageProducer;//消息生产者//实例化连接工厂connectionFactory=new org.apache.activemq.ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);try {connection=connectionFactory.createConnection();// 通过连接工厂获取连接connection.start();//启动连接session=connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);// 创建Sessiondestination=session.createQueue("HelloWorld");//创建一个HelloWorld的消息队列messageProducer=session.createProducer(destination);//创建消息生产者sendMessage(session, messageProducer);//发送消息session.commit();} catch (JMSException e) {e.printStackTrace();}finally {if(connection!=null) {try {connection.close();} catch (JMSException e) {e.printStackTrace();}}}}/** * 发送消息 * @author fendo * @param session * @param messageProducer * @throws JMSException */public static void sendMessage(Session session ,MessageProducer messageProducer) throws JMSException {for(int i=0;i<JMSProducer.SENDNUM;i++) {TextMessage message=session.createTextMessage("ActiveMQ发送的消息:"+i);System.out.println("发送的消息:"+"ActiveMQ发送的消息:"+i);messageProducer.send(message);}}}


2)消费者

package com.fendo.mq;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.MessageConsumer;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;/** * 消费者 * @author fendo * */public class JMSConsumer_Receive {private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址public static void main(String[] args) {ConnectionFactory connectionFactory; // 连接工厂Connection connection = null; // 连接Session session; // 会话 接受或者发送消息的线程Destination destination; // 消息的目的地MessageConsumer messageConsumer; // 消息的消费者// 实例化连接工厂connectionFactory=new ActiveMQConnectionFactory(JMSConsumer_Receive.USERNAME, JMSConsumer_Receive.PASSWORD, JMSConsumer_Receive.BROKEURL);try {connection=connectionFactory.createConnection();  // 通过连接工厂获取连接connection.start(); // 启动连接session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Sessiondestination=session.createQueue("HelloWorld");  // 创建连接的消息队列 (注意:队列名要和生产者那边相同)messageConsumer=session.createConsumer(destination); // 创建消息消费者while(true){TextMessage textMessage=(TextMessage)messageConsumer.receive(100000);//设置多少秒接受一次if(textMessage!=null){System.out.println("收到的消息:"+textMessage.getText());}else{break;}}} catch (JMSException e) {e.printStackTrace();}finally {try {connection.close();} catch (JMSException e) {e.printStackTrace();}}}}

B)使用Listener监听方式


1)生产者

生产者类不变,和上面一样。


2)消费者

package com.fendo.mq;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageConsumer;import javax.jms.MessageListener;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;/** * 消费者 * @author fendo * */public class JMSConsumer_Listener {private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址public static void main(String[] args) {ConnectionFactory connectionFactory; // 连接工厂Connection connection = null; // 连接Session session; // 会话 接受或者发送消息的线程Destination destination; // 消息的目的地MessageConsumer messageConsumer; // 消息的消费者// 实例化连接工厂connectionFactory=new ActiveMQConnectionFactory(JMSConsumer_Listener.USERNAME, JMSConsumer_Listener.PASSWORD, JMSConsumer_Listener.BROKEURL);try {connection=connectionFactory.createConnection();  // 通过连接工厂获取连接connection.start(); // 启动连接session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Sessiondestination=session.createQueue("HelloWorld");  // 创建连接的消息队列messageConsumer=session.createConsumer(destination); // 创建消息消费者JMSConsumer_Listener jmsConsumer_Listener=new JMSConsumer_Listener();messageConsumer.setMessageListener(jmsConsumer_Listener.new Listener());} catch (JMSException e) {e.printStackTrace();} }/** * 消息监听 * @author fendo * */public class Listener implements MessageListener{@Overridepublic void onMessage(Message message) {try {System.out.println("接收到的消息:"+((TextMessage)message).getText());} catch (JMSException e) {e.printStackTrace();}}}}

完整示例:http://download.csdn.net/detail/u011781521/9907601

阅读全文
1 0
原创粉丝点击