activemq的几种基本通信方式总结.docx

上传人:b****3 文档编号:4413921 上传时间:2022-12-01 格式:DOCX 页数:18 大小:106.26KB
下载 相关 举报
activemq的几种基本通信方式总结.docx_第1页
第1页 / 共18页
activemq的几种基本通信方式总结.docx_第2页
第2页 / 共18页
activemq的几种基本通信方式总结.docx_第3页
第3页 / 共18页
activemq的几种基本通信方式总结.docx_第4页
第4页 / 共18页
activemq的几种基本通信方式总结.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

activemq的几种基本通信方式总结.docx

《activemq的几种基本通信方式总结.docx》由会员分享,可在线阅读,更多相关《activemq的几种基本通信方式总结.docx(18页珍藏版)》请在冰豆网上搜索。

activemq的几种基本通信方式总结.docx

activemq的几种基本通信方式总结

ActiveMQ的几种基本通信方式总结

简介

   在前面一篇文章里讨论过几种应用系统集成的方式,发现实际上面向消息队列的集成方案算是一个总体比较合理的选择。

这里,我们先针对具体的一个消息队列Activemq的基本通信方式进行探讨。

activemq是JMS消息通信规范的一个实现。

总的来说,消息规范里面定义最常见的几种消息通信模式主要有发布-订阅、点对点这两种。

另外,通过结合这些模式的具体应用,我们在处理某些应用场景的时候也衍生出来了一种请求应答的模式。

下面,我们针对这几种方式一一讨论一下。

 

基础流程

  在讨论具体方式的时候,我们先看看使用activemq需要启动服务的主要过程。

  按照JMS的规范,我们首先需要获得一个JMSconnectionfactory.,通过这个connectionfactory来创建connection.在这个基础之上我们再创建session,destination,producer和consumer。

因此主要的几个步骤如下:

1.获得JMSconnectionfactory.通过我们提供特定环境的连接信息来构造factory。

2.利用factory构造JMSconnection

3.启动connection

4.通过connection创建JMSsession.

5.指定JMSdestination.

6.创建JMSproducer或者创建JMSmessage并提供destination.

7.创建JMSconsumer或注册JMSmessagelistener.

8.发送和接收JMSmessage.

9.关闭所有JMS资源,包括connection,session,producer,consumer等。

 

publish-subscribe

   发布订阅模式有点类似于我们日常生活中订阅报纸。

每年到年尾的时候,邮局就会发一本报纸集合让我们来选择订阅哪一个。

在这个表里头列了所有出版发行的报纸,那么对于我们每一个订阅者来说,我们可以选择一份或者多份报纸。

比如北京日报、潇湘晨报等。

那么这些个我们订阅的报纸,就相当于发布订阅模式里的topic。

有很多个人订阅报纸,也有人可能和我订阅了相同的报纸。

那么,在这里,相当于我们在同一个topic里注册了。

对于一份报纸发行方来说,它和所有的订阅者就构成了一个1对多的关系。

这种关系如下图所示:

   现在,假定我们用前面讨论的场景来写一个简单的示例。

我们首先需要定义的是publisher.

publisher

   publisher是属于发布信息的一方,它通过定义一个或者多个topic,然后给这些topic发送消息。

  publisher的构造函数如下:

Java代码  

1.public Publisher() throws JMSException {  

2.        factory = new ActiveMQConnectionFactory(brokerURL);  

3.        connection = factory.createConnection();  

4.        try {  

5.        connection.start();  

6.        } catch (JMSException jmse) {  

7.            connection.close();  

8.            throw jmse;  

9.        }  

10.        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  

11.        producer = session.createProducer(null);  

12.    }  

   我们按照前面说的流程定义了基本的connectionFactory,connection,session,producer。

这里代码就是主要实现初始化的效果。

  接着,我们需要定义一系列的topic让所有的consumer来订阅,设置topic的代码如下:

Java代码  

1.protected void setTopics(String[] stocks) throws JMSException {  

2.    destinations = new Destination[stocks.length];  

3.    for(int i = 0; i < stocks.length; i++) {  

4.        destinations[i] = session.createTopic("STOCKS." + stocks[i]);  

5.    }  

6.}  

   这里destinations是一个内部定义的成员变量Destination[]。

这里我们总共定义了的topic数取决于给定的参数stocks。

   在定义好topic之后我们要给这些指定的topic发消息,具体实现的代码如下:

Java代码  

1.protected void sendMessage(String[] stocks) throws JMSException {  

2.    for(int i = 0; i < stocks.length; i++) {  

3.        Message message = createStockMessage(stocks[i], session);  

4.        System.out.println("Sending:

 " + ((ActiveMQMapMessage)message).getContentMap() + " on destination:

 " + destinations[i]);  

5.        producer.send(destinations[i], message);  

6.    }  

7.}  

8.  

9.protected Message createStockMessage(String stock, Session session) throws JMSException {  

10.    MapMessage message = session.createMapMessage();  

11.    message.setString("stock", stock);  

12.    message.setDouble("price", 1.00);  

13.    message.setDouble("offer", 0.01);  

14.    message.setBoolean("up", true);  

15.          

16.    return message;  

17.}  

   前面的代码很简单,在sendMessage方法里我们遍历每个topic,然后给每个topic发送定义的Message消息。

  在定义好前面发送消息的基础之后,我们调用他们的代码就很简单了:

Java代码  

1.public static void main(String[] args) throws JMSException {  

2.    if(args.length < 1)  

3.        throw new IllegalArgumentException();  

4.      

5.        // Create publisher       

6.        Publisher publisher = new Publisher();  

7.          

8.        // Set topics  

9.    publisher.setTopics(args);  

10.          

11.    for(int i = 0; i < 10; i++) {  

12.        publisher.sendMessage(args);  

13.        System.out.println("Publisher '" + i + " price messages");  

14.        try {  

15.            Thread.sleep(1000);  

16.        } catch(InterruptedException e) {  

17.            e.printStackTrace();  

18.        }  

19.    }  

20.    // Close all resources  

21.    publisher.close();  

22.}  

   调用他们的代码就是我们遍历所有topic,然后通过sendMessage发送消息。

在发送一个消息之后先sleep1秒钟。

要注意的一个地方就是我们使用完资源之后必须要使用close方法将这些资源关闭释放。

close方法关闭资源的具体实现如下:

Java代码  

1.public void close() throws JMSException {  

2.    if (connection !

= null) {  

3.        connection.close();  

4.     }  

5.}  

 

consumer

  Consumer的代码也很类似,具体的步骤无非就是1.初始化资源。

2.接收消息。

3.必要的时候关闭资源。

  初始化资源可以放到构造函数里面:

Java代码  

1.public Consumer() throws JMSException {  

2.        factory = new ActiveMQConnectionFactory(brokerURL);  

3.        connection = factory.createConnection();  

4.        connection.start();  

5.        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  

6.    }  

   接收和处理消息的方法有两种,分为同步和异步的,一般同步的方式我们是通过MessageConsumer.receive()方法来处理接收到的消息。

而异步的方法则是通过注册一个MessageListener的方法,使用MessageConsumer.setMessageListener()。

这里我们采用异步的方式实现:

Java代码  

1.public static void main(String[] args) throws JMSException {  

2.    Consumer consumer = new Consumer();  

3.    for (String stock :

 args) {  

4.    Destination destination = consumer.getSession().createTopic("STOCKS." + stock);  

5.    MessageConsumer messageConsumer = consumer.getSession().createConsumer(destination);  

6.    messageConsumer.setMessageListener(new Listener());  

7.    }  

8.}  

9.      

10.public Session getSession() {  

11.    return session;  

12.}  

   在前面的代码里我们先找到同样的topic,然后遍历所有的topic去获得消息。

对于消息的处理我们专门通过Listener对象来负责。

  Listener对象的职责很简单,主要就是处理接收到的消息:

Java代码  

1.public class Listener implements MessageListener {  

2.  

3.    public void onMessage(Message message) {  

4.        try {  

5.            MapMessage map = (MapMessage)message;  

6.            String stock = map.getString("stock");  

7.            double price = map.getDouble("price");  

8.            double offer = map.getDouble("offer");  

9.            boolean up = map.getBoolean("up");  

10.            DecimalFormat df = new DecimalFormat( "#,###,###,##0.00" );  

11.            System.out.println(stock + "\t" + df.format(price) + "\t" + df.format(offer) + "\t" + (up?

"up":

"down"));  

12.        } catch (Exception e) {  

13.            e.printStackTrace();  

14.        }  

15.    }  

16.  

17.}  

  它实现了MessageListener接口,里面的onMessage方法就是在接收到消息之后会被调用的方法。

  现在,通过实现前面的publisher和consumer我们已经实现了pub-sub模式的一个实例。

仔细回想它的步骤的话,主要就是要两者设定一个共同的topic,有了这个topic之后他们可以实现一方发消息另外一方接收。

另外,为了连接到具体的messageserver,这里是使用了连接tcp:

//localhost:

16161作为定义ActiveMQConnectionFactory的路径。

在publisher端通过session创建producer,根据指定的参数创建destination,然后将消息和destination作为producer.send()方法的参数发消息。

在consumer端也要创建类似的connection,session。

通过session得到destination,再通过session.createConsumer(destination)来得到一个MessageConsumer对象。

有了这个MessageConsumer我们就可以自行选择是直接同步的receive消息还是注册listener了。

p2p

  p2p的过程则理解起来更加简单。

它好比是两个人打电话,这两个人是独享这一条通信链路的。

一方发送消息,另外一方接收,就这么简单。

在实际应用中因为有多个用户对使用p2p的链路,它的通信场景如下图所示:

  我们再来看看一个p2p的示例:

  在p2p的场景里,相互通信的双方是通过一个类似于队列的方式来进行交流。

和前面pub-sub的区别在于一个topic有一个发送者和多个接收者,而在p2p里一个queue只有一个发送者和一个接收者。

发送者

  和前面的示例非常相似,我们构造函数里需要初始化的内容基本上差不多:

 

Java代码  

1.public Publisher() throws JMSException {  

2.    factory = new ActiveMQConnectionFactory(brokerURL);  

3.    connection = factory.createConnection();  

4.    connection.start();  

5.    session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  

6.    producer = session.createProducer(null);  

7.}  

   发送消息的方法如下:

 

 

Java代码  

1.public void sendMessage() throws JMSException {  

2.    for(int i = 0; i < jobs.length; i++)  

3.    {  

4.        String job = jobs[i];  

5.        Destination destination = session.createQueue("JOBS." + job);  

6.        Message message = session.createObjectMessage(i);  

7.        System.out.println("Sending:

 id:

 " + ((ObjectMessage)message).getObject() + " on queue:

 " + destination);  

8.        producer.send(destination, message);  

9.    }  

10.}  

   这里我们定义了一个jobs的数组,通过遍历这个数组来创建不同的jobqueue。

这样就相当于建立了多个点对点通信的链路。

 

  消息发送者的启动代码如下:

 

Java代码  

1.public static void main(String[] args) throws JMSException {  

2.    Publisher publisher = new Publisher();  

3.    for(int i = 0; i < 10; i++) {  

4.        publisher.sendMessage();  

5.        System.out.println("Published " + i + " job messages");  

6.    try {  

7.            Thread.sleep(1000);  

8.        } catch (InterruptedException x) {  

9.        e.printStackTrace();  

10.        }  

11.    }  

12.    publisher.close();  

13.}  

   我们在这里发送10条消息,当然,在每个sendMessage的方法里实际上是针对每个queue发送了10条。

 

 

接收者

   接收者的代码很简单,一个构造函数初始化所有的资源:

 

Java代码  

1.public Consumer() throws JMSException {  

2.        factory = new ActiveMQConnectionFactory(brokerURL);  

3.        connection = factory.createConnection();  

4.        connection.start();  

5.        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);  

6.    }  

  还有一个就是注册消息处理的对象:

 

 

Java代码  

1.public static void main(String[] args) throws JMSException {  

2.        Consumer consumer = new Consumer();  

3.        for (String job :

 consumer.jobs) {  

4.            Destination destination = consumer.getSession().createQueue("JOBS." + job);  

5.            MessageConsumer messageConsumer = consumer.getSession().createConsumer(destination);  

6.            messageConsumer.setMessageListener(new Listener(job));  

7.        }  

8.    }  

9.      

10.    public Session getSession() {  

11.        return session;  

12.    }  

   具体注册的对象处理方法和前面还是类似,实现MessageListener接口就可以了。

Java代码  

1.import javax.jms.Message;  

2.import javax.jms.MessageListener;  

3.import javax.jms.ObjectMessage;  

4.  

5.public class Listener implements MessageListener {  

6.  

7.    private String job;  

8.      

9.    public Listener(String job) {  

10.        this.job = job;  

11.    }  

12.  

13.    public void onMessage(Message message) {  

14.        try {  

15.            //do something here  

16.            System.out.println(job + " id:

" + ((ObjectMessage)me

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1