ActiveMQ消息队列的使用学习笔记

ActiveMQ的特点

1. 多种语言和协议编写客户端。语言: Java, C, C++, C#, Ruby, Perl, Python, PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP

2. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)

3. 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性

4. 通过了常见J2EE服务器(如 Geronimo,JBoss 4, GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上

5. 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA

6. 支持通过JDBC和journal提供高速的消息持久化

7. 从设计上保证了高性能的集群,客户端-服务器,点对点

8. 支持Ajax

9. 支持与Axis的整合

10. 可以很容易得调用内嵌JMS provider,进行测试

ActiveMQ的消息形式

对于消息的传递有两种类型:

一种是点对点的,即一个生产者和一个消费者一一对应;

另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。

JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

 · StreamMessage -- Java原始值的数据流

 · MapMessage--一套名称-值对

 · TextMessage--一个字符串对象

 · ObjectMessage--一个序列化的 Java对象

 · BytesMessage--一个字节的数据流

ActiveMQ的安装

度娘有的你就有了,这里就不叨叨。。。。。。。

接下来我们说说消息队列的使用方法

ActiveMQ的使用

       在分布式开发的时候,不同服务之间会进行通信,例如A服务在进行数据操作的时候,对其他服务产生了影响,呢么这就需要通知这个服务,以免产生不必要的异常,ActiveMQ这个时候就发挥作用了,可以用他来进行不同服务间的通讯。我们来说说他。

点对点的模式Queue:

Producer:生产者:生产消息,发送端。

第一步:创建ConnectionFactory对象,需要指定服务端ip及端口号。

第二步:使用ConnectionFactory对象创建一个Connection对象。

第三步:开启连接,调用Connection对象的start方法。

第四步:使用Connection对象创建一个Session对象。

第五步:使用Session对象创建一个Destination对象(topic、queue),此处创建一个Queue对象。

第六步:使用Session对象创建一个Producer对象。

第七步:创建一个Message对象,创建一个TextMessage对象。

第八步:使用Producer对象发送消息。

第九步:关闭资源。

以下是测试的代码:

@Test

    publicvoid testQueueProducer() throws Exception {

        // 第一步:创建ConnectionFactory对象,需要指定服务端ip及端口号。

        //brokerURL服务器的ip及端口号

        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.168:61616");

        // 第二步:使用ConnectionFactory对象创建一个Connection对象。

        Connection connection = connectionFactory.createConnection();

        // 第三步:开启连接,调用Connection对象的start方法。

        connection.start();

        // 第四步:使用Connection对象创建一个Session对象。

        //第一个参数:是否开启事务。true:开启事务,第二个参数忽略。

        //第二个参数:当第一个参数为false时,才有意义。消息的应答模式。1、自动应答2、手动应答。一般是自动应答。

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

        // 第五步:使用Session对象创建一个Destination对象(topic、queue),此处创建一个Queue对象。

        //参数:队列的名称。

        Queue queue = session.createQueue("test-queue");

        // 第六步:使用Session对象创建一个Producer对象。

        MessageProducer producer = session.createProducer(queue);

        // 第七步:创建一个Message对象,创建一个TextMessage对象。

        TextMessage textMessage = session.createTextMessage("hello activeMq,this is my first test.");

        // 第八步:使用Producer对象发送消息。

        producer.send(textMessage);

        // 第九步:关闭资源。

        producer.close();

        session.close();

        connection.close();

    }

Consumer:消费者:接收消息。

第一步:创建一个ConnectionFactory对象。

第二步:从ConnectionFactory对象中获得一个Connection对象。

第三步:开启连接。调用Connection对象的start方法。

第四步:使用Connection对象创建一个Session对象。

第五步:使用Session对象创建一个Destination对象。和发送端保持一致queue,并且队列的名称一致。

第六步:使用Session对象创建一个Consumer对象。

第七步:接收消息。

第八步:打印消息。

第九步:关闭资源

测试代码:

@Test

   publicvoid testQueueConsumer() throws Exception {

      // 第一步:创建一个ConnectionFactory对象。

      ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.168:61616");

      // 第二步:从ConnectionFactory对象中获得一个Connection对象。

      Connection connection = connectionFactory.createConnection();

      // 第三步:开启连接。调用Connection对象的start方法。

      connection.start();

      // 第四步:使用Connection对象创建一个Session对象。

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

      // 第五步:使用Session对象创建一个Destination对象。和发送端保持一致queue,并且队列的名称一致。

      Queue queue = session.createQueue("test-queue");

      // 第六步:使用Session对象创建一个Consumer对象。

      MessageConsumer consumer = session.createConsumer(queue);

      // 第七步:接收消息。

      consumer.setMessageListener(new MessageListener() {

        

         @Override

         publicvoid onMessage(Message message) {

            try {

               TextMessage textMessage = (TextMessage) message;

               String text = null;

               //取消息的内容

               text = textMessage.getText();

               // 第八步:打印消息。

               System.out.println(text);

            } catch (JMSException e) {

               e.printStackTrace();

            }

         }

      });

      //等待键盘输入

      System.in.read();

      // 第九步:关闭资源

      consumer.close();

      session.close();

      connection.close();

   }

 

      Queue点对点的模式,当消息发布后,保存在消息队列的服务器上,如果消费者接收了(消费了)这个消息,呢么这个消息队列就不存在了,如果不被消费,则会永久保存。

发布/订阅模式Topic:

Producer:

第一步:创建ConnectionFactory对象,需要指定服务端ip及端口号。

第二步:使用ConnectionFactory对象创建一个Connection对象。

第三步:开启连接,调用Connection对象的start方法。

第四步:使用Connection对象创建一个Session对象。

第五步:使用Session对象创建一个Destination对象(topic、queue),此处创建一个Topic对象。

第六步:使用Session对象创建一个Producer对象。

第七步:创建一个Message对象,创建一个TextMessage对象。

第八步:使用Producer对象发送消息。

第九步:关闭资源。

@Test

   publicvoid testTopicProducer() throws Exception {

      // 第一步:创建ConnectionFactory对象,需要指定服务端ip及端口号。

      // brokerURL服务器的ip及端口号

      ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.168:61616");

      // 第二步:使用ConnectionFactory对象创建一个Connection对象。

      Connection connection = connectionFactory.createConnection();

      // 第三步:开启连接,调用Connection对象的start方法。

      connection.start();

      // 第四步:使用Connection对象创建一个Session对象。

      // 第一个参数:是否开启事务。true:开启事务,第二个参数忽略。

      // 第二个参数:当第一个参数为false时,才有意义。消息的应答模式。1、自动应答2、手动应答。一般是自动应答。

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

      // 第五步:使用Session对象创建一个Destination对象(topic、queue),此处创建一个topic对象。

      // 参数:话题的名称。

      Topic topic = session.createTopic("test-topic");

      // 第六步:使用Session对象创建一个Producer对象。

      MessageProducer producer = session.createProducer(topic);

      // 第七步:创建一个Message对象,创建一个TextMessage对象。

      /*

       * TextMessage message = new ActiveMQTextMessage(); message.setText(

       * "hello activeMq,this is my first test.");

       */

      TextMessage textMessage = session.createTextMessage("hello activeMq,this is my topic test");

      // 第八步:使用Producer对象发送消息。

      producer.send(textMessage);

      // 第九步:关闭资源。

      producer.close();

      session.close();

      connection.close();

}

Consumer:

第一步:创建一个ConnectionFactory对象。

第二步:从ConnectionFactory对象中获得一个Connection对象。

第三步:开启连接。调用Connection对象的start方法。

第四步:使用Connection对象创建一个Session对象。

第五步:使用Session对象创建一个Destination对象。和发送端保持一致topic,并且话题的名称一致。

第六步:使用Session对象创建一个Consumer对象。

第七步:接收消息。

第八步:打印消息。

第九步:关闭资源

@Test

   publicvoid testTopicConsumer() throws Exception {

      // 第一步:创建一个ConnectionFactory对象。

      ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.168:61616");

      // 第二步:从ConnectionFactory对象中获得一个Connection对象。

      Connection connection = connectionFactory.createConnection();

      // 第三步:开启连接。调用Connection对象的start方法。

      connection.start();

      // 第四步:使用Connection对象创建一个Session对象。

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

      // 第五步:使用Session对象创建一个Destination对象。和发送端保持一致topic,并且话题的名称一致。

      Topic topic = session.createTopic("test-topic");

      // 第六步:使用Session对象创建一个Consumer对象。

      MessageConsumer consumer = session.createConsumer(topic);

      // 第七步:接收消息。

      consumer.setMessageListener(new MessageListener() {

 

         @Override

         publicvoid onMessage(Message message) {

            try {

               TextMessage textMessage = (TextMessage) message;

               String text = null;

               // 取消息的内容

               text = textMessage.getText();

               // 第八步:打印消息。

               System.out.println(text);

            } catch (JMSException e) {

               e.printStackTrace();

            }

         }

      });

      System.out.println("topic的消费端03。。。。。");

      // 等待键盘输入

      System.in.read();

      // 第九步:关闭资源

      consumer.close();

      session.close();

      connection.close();

   }

在进行测试的时候,要让消费者运行,topic发布消息的时候,是广播,广播出去后就不复存在了,消费者如果运行,则会接收到消息,如果没有运行,则接受不到消息,默认情况下,topic发送的消息是不会被保存在服务器端的,但是我们可以设置,将topic发送的消息保存到服务器,在这里也不叨叨了,度娘有(哈哈)。。。。。。

到这里,对ActiveMQ的消息发送与接收就完成了,但是怎么用到我们的项目中去呢?接下里就说说在项目中的运用。

项目中使用ActiveMQ(针对SSM框架):

1.   在spring的配置文件中注册

2.    <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->

3.    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

4.          <property name="brokerURL" value="tcp://192.168.25.161:61616" />

5.    </bean>

6.    <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->

7.    <bean id="connectionFactory"

8.    class="org.springframework.jms.connection.SingleConnectionFactory">

9.          <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->

10.      <property name="targetConnectionFactory" ref="targetConnectionFactory" />

11. </bean>

12. <!-- 配置生产者 -->

13. <!-- Spring提供的JMS工具类,它可以进行消息发送、接收等 -->

14. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">

15.      <!-- 这个connectionFactory对应的是我们定义的Spring提供的那个ConnectionFactory对象 -->

16.      <property name="connectionFactory" ref="connectionFactory" />

17. </bean>

18. <!--这个是队列目的地,点对点的 -->

19. <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">

20.      <constructor-arg>

21.            <value>spring-queue</value>

22.      </constructor-arg>

23. </bean>

24. <!--这个是主题目的地,一对多的 -->

25. <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">

26.      <constructor-arg value="itemAddTopic" />

27. </bean>

2.项目中消息的发送

jmsTemplate.send(topicDestination, new MessageCreator() {

                 @Override

                 public Message createMessage(Session session) throws JMSException {

                      TextMessage textMessage = session.createTextMessage(“消息”);

                      return textMessage;

                 }

           });

 

3.接受消息文件的配置

<!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->

      <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

           <property name="brokerURL" value="tcp://192.168.25.161:61616" />

      </bean>

      <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->

      <bean id="connectionFactory"

            class="org.springframework.jms.connection.SingleConnectionFactory">

           <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory -->

           <property name="targetConnectionFactory" ref="targetConnectionFactory" />

      </bean>

      <!--这个是队列目的地,点对点的 -->

      <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">

           <constructor-arg>

                 <value>spring-queue</value>

           </constructor-arg>

      </bean>

      <!--这个是主题目的地,一对多的 -->

      <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">

           <constructor-arg value="itemAddTopic" />

      </bean>

      <bean id="myMessageListener" class="cn.e3mall.search.message.MyMessageListener"/>

      <!-- 消息监听容器 -->

      <bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">

           <property name="connectionFactory" ref="connectionFactory" />

           <property name="destination" ref="queueDestination" />

           <property name="messageListener" ref="myMessageListener" />

      </bean>

      <!-- 监听商品添加消息,同步索引库 -->

      <bean id="itemAddMessageListener" class="cn.e3mall.search.message.ItemAddMessageListener"/>

      <bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">

           <property name="connectionFactory" ref="connectionFactory" />

           <property name="destination" ref="topicDestination" />

           <property name="messageListener" ref="itemAddMessageListener" />

      </bean>

4.接受消息

public class ItemAddMessageListener implements MessageListener {

     

      @Autowired

      private ItemMapper itemMapper;

      @Autowired

      private SolrServer solrServer;

 

      @Override

      public void onMessage(Message message) {

           try {

                 //从消息中取消息

                 TextMessage textMessage = (TextMessage) message;

                 String text = textMessage.getText();

                 //业务逻辑操作

           } catch (Exception e) {

                 e.printStackTrace();

           }

      }

}

 

到这里ActiveMQ消息队列进行服务件的通信就完成了。

 


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值