ActiveMQ搭建与测试

来源:互联网 发布:一些计算机算法的例子 编辑:程序博客网 时间:2024/05/29 10:32

 

ActiveMQ 是Apache出品的最流行的,能力强劲的开源消息总线JMS(Java Message Service)。ActiveMQ有两种消息处理模式Topic和Queue。以下均已linux环境为例

一、  Topic和Queue介绍

 

Topic

Queue

概要

Publish Subscribe messaging 发布订阅消息

Point-to-Point 点对点

有无状态

Topic数据默认不落地,是无状态的

Queue数据默认会在mq服务器上以文件形式保存,比如Active MQ一般保存在$AMQ_HOME\data\kr-store\data下面。也可以配置成DB存储

完整性保障

并不保证publisher发布的每条数据,Subscriber都能接收到

Queue保证每条数据都能被receiver接收

消息是否会丢失

一般来说publisher发布消息到某一个topic时,只有正在监听该topic地址的sub能够接收到消息;如果没有sub在监听,该topic就丢失了

Sender发送消息到目标Queue,receiver可以异步接收这个Queue上的消息。Queue上的消息如果暂时没有receiver来取,也不会丢失。

消息发布接收策略

一对多的消息发布接收策略,监听同一个topic地址的多个sub都能收到publisher发送的消息。Sub接收完通知mq服务器

一对一的消息发布接收策略,一个sender发送的消息,只能有一个receiver接收。receiver接收完后,通知mq服务器已接收,mq服务器对queue里的消息采取删除或其他操作

Topic和Queue的最大区别在于Topic是以广播的形式,通知所有在线监听的客户端有新的消息,没有监听的客户端将收不到消息;而Queue则是以点对点的形式通知多个处于监听状态的客户端中的一个。

 

二、下载和安装ActiveMQ

1、下载

ActiveMQ的最新版本是5.13.1,下载地址:http://activemq.apache.org/activemq-5131-release.html。

 

2、安装

解压下载的apache-activemq-5.13.1-bin.tar.gz包,ActiveMQ的默认服务端口:61616、默认console端口:8161。

 

3、运行命令

bin目录下执行./activemq start/stop/restart命令分别表示启动/停止/重启

 

4、修改ActiveMQ的服务端口和console端口

A、修改服务地址和端口:打开conf/activemq.xml文件,找到如下部分,修改红色部分即可:

<transportConnectorname="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>

B、修改console地址和端口:打开conf/jetty.xml文件,找到如下部分,修改红色部分即可:

<beanid="jettyPort"class="org.apache.activemq.web.WebConsolePort"init-method="start">

             <!-- the default port number forthe web console -->

        <property name="host"value="0.0.0.0"/>

        <property name="port"value="8161"/>

</bean>

 

三、测试ActiveMQ(分Topic和Queue两种情况介绍)

现有测试服务器:192.168.0.59/90/91

在服务器59上安装好ActiveMQ(使用默认端口),并启动

1、    Topic模式

1)    producer代码

package com.syk.activemq.demo;

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Destination;

import javax.jms.MessageProducer;

import javax.jms.Session;

import javax.jms.TextMessage;

 

import org.apache.activemq.ActiveMQConnection;

import org.apache.activemq.ActiveMQConnectionFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

/**

 *

 * @author syk

 * activemq 生产者实例

 *

 */

public class ProducerTopic {

 

final static Logger logger =LoggerFactory.getLogger(ProducerTopic.class);

private static final int SEND_NUMBER= 5;

public static void main(String[]args) {

   //ConnectionFactory:连接工厂,JMS用它创建连接

   ConnectionFactoryconnectionFactory;

   //Connection:JMS客户端到JMS Provider的连接

   Connection connection = null;

   //Session:发送消息的线程

   Session session;

   //Destination:消息的目的地(消息发送给谁)

   Destination destination;

   //生产者:消息发送者

   MessageProducer producer;

  

   try {

      //构造ConnectionFactory实例对象

      connectionFactory = newActiveMQConnectionFactory(

           ActiveMQConnection.DEFAULT_USER,

           ActiveMQConnection.DEFAULT_PASSWORD,

           "tcp://192.168.0.59:61616");

      //从工厂得到连接对象

      connection =connectionFactory.createConnection();

      //启动

      connection.start();

      //获取操作连接

      session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);

      //创建目的地队列

      destination =session.createTopic("test_topic");

      //创建消息生产者

      producer =session.createProducer(destination);

      //调用发送消息方法

      sendMessage(session, producer);

      session.commit();

   } catch (Exception e) {

      logger.error(e.getMessage(), e);

   } finally {

      if(null != connection){

         try {

           connection.close();

         } catch (Exception e) {

           logger.error(e.getMessage(),e);

         }

      }

   }

}

public static voidsendMessage(Session session, MessageProducer producer) throws Exception{

   for (int i = 1; i <=SEND_NUMBER; i++) {

      TextMessage message =session.createTextMessage("ActiveMQ发送的消息" + i);

      //发送消息到目的地

      producer.send(message);

      logger.info("send message{}", i);

   }

}

}

 

2)    consumer代码

package com.syk.activemq.demo;

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Destination;

import javax.jms.MessageConsumer;

import javax.jms.Session;

import javax.jms.TextMessage;

 

import org.apache.activemq.ActiveMQConnection;

import org.apache.activemq.ActiveMQConnectionFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

/**

 *

 * @author syk

 * activemq 消费者实例

 *

 */

public class ConsumerTopic implements Runnable {

 

final static Logger logger =LoggerFactory.getLogger(ConsumerTopic.class);

private String threadName;

public ConsumerTopic(StringthreadName) {

   super();

   this.threadName = threadName;

}

 

public static void main(String[]args) {

   //这里启动3个线程来监听test_topic的消息,与queue的方式不一样三个线程都能收到同样的消息

   ConsumerTopic topic1 = newConsumerTopic("thread1");

   ConsumerTopic topic2 = newConsumerTopic("thread2");

   ConsumerTopic topic3 = newConsumerTopic("thread3");

   Threadthread1 = new Thread(topic1);

   Thread thread2 = newThread(topic2);

   Thread thread3 = newThread(topic3);

   thread1.start();

   thread2.start();

   thread3.start();

}

 

@Override

public void run() {

 

   //ConnectionFactory:连接工厂,JMS用它创建连接

   ConnectionFactoryconnectionFactory;

   //Connection:JMS客户端到JMS Provider的连接

   Connection connection = null;

   //Session:接收消息的线程

   Session session;

   //Destination:从生产者得到消息

   Destination destination;

   //消费者:消息接收者

   MessageConsumer consumer;

   try {

      //构造ConnectionFactory实例对象

      connectionFactory = newActiveMQConnectionFactory(

           ActiveMQConnection.DEFAULT_USER,

           ActiveMQConnection.DEFAULT_PASSWORD,

           "tcp://192.168.0.59:61616");

      //从工厂得到连接对象

      connection =connectionFactory.createConnection();

      //启动

      connection.start();

      //获取操作连接

      session =connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

      //创建目的地队列

      destination =session.createTopic("test_topic");

      //创建消息接收者

      consumer =session.createConsumer(destination);

      while(true){

         TextMessage message =(TextMessage)consumer.receive(500000);

         if(null != message){

           logger.info("线程" + threadName + "收到消息" + message.getText());

         }else{

           continue;

         }

      }

   } catch (Exception e) {

      logger.error(e.getMessage(), e);

   } finally {

      if(null != connection){

         try {

           connection.close();

         } catch (Exception e) {

           logger.error(e.getMessage(),e);

         }

      }

   }

  

}

}

 

2、    Queue模式

1)    producer代码

package com.syk.activemq.demo;

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Destination;

import javax.jms.MessageProducer;

import javax.jms.Session;

import javax.jms.TextMessage;

 

import org.apache.activemq.ActiveMQConnection;

import org.apache.activemq.ActiveMQConnectionFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

/**

 *

 * @author syk

 * activemq 生产者实例

 *

 */

public class ProducerQueue {

 

final static Logger logger =LoggerFactory.getLogger(ProducerQueue.class);

private static final int SEND_NUMBER= 5;

public static void main(String[]args) {

   //ConnectionFactory:连接工厂,JMS用它创建连接

   ConnectionFactoryconnectionFactory;

   //Connection:JMS客户端到JMS Provider的连接

   Connection connection = null;

   //Session:发送消息的线程

   Session session;

   //Destination:消息的目的地(消息发送给谁)

   Destination destination;

   //生产者:消息发送者

   MessageProducer producer;

  

   try {

      //构造ConnectionFactory实例对象

      connectionFactory = newActiveMQConnectionFactory(

           ActiveMQConnection.DEFAULT_USER,

           ActiveMQConnection.DEFAULT_PASSWORD,

           "tcp://192.168.0.59:61616");

      //从工厂得到连接对象

      connection =connectionFactory.createConnection();

      //启动

      connection.start();

      //获取操作连接

      session =connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

      //创建目的地队列

      destination = session.createQueue("test_queue");

      //创建消息生产者

      producer =session.createProducer(destination);

      //调用发送消息方法

      sendMessage(session, producer);

      session.commit();

   } catch (Exception e) {

      logger.error(e.getMessage(), e);

   } finally {

      if(null != connection){

         try {

           connection.close();

         } catch (Exception e) {

           logger.error(e.getMessage(),e);

         }

      }

   }

}

public static voidsendMessage(Session session, MessageProducer producer) throws Exception{

   for (int i = 1; i <=SEND_NUMBER; i++) {

      TextMessage message =session.createTextMessage("ActiveMQ发送的消息" + i);

      //发送消息到目的地

      producer.send(message);

      logger.info("send message{}", i);

   }

}

}

 

2)    consumer代码

package com.syk.activemq.demo;

 

import javax.jms.Connection;

import javax.jms.ConnectionFactory;

import javax.jms.Destination;

import javax.jms.MessageConsumer;

import javax.jms.Session;

import javax.jms.TextMessage;

 

import org.apache.activemq.ActiveMQConnection;

import org.apache.activemq.ActiveMQConnectionFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

/**

 *

 * @author syk

 * activemq 消费者实例

 *

 */

public class ConsumerQueue {

 

final static Logger logger =LoggerFactory.getLogger(ConsumerQueue.class);

public static void main(String[]args) {

   //ConnectionFactory:连接工厂,JMS用它创建连接

   ConnectionFactoryconnectionFactory;

   //Connection:JMS客户端到JMS Provider的连接

   Connection connection = null;

   //Session:接收消息的线程

   Session session;

   //Destination:从生产者得到消息

   Destination destination;

   //消费者:消息接收者

   MessageConsumer consumer;

   try {

      //构造ConnectionFactory实例对象

      connectionFactory = newActiveMQConnectionFactory(

           ActiveMQConnection.DEFAULT_USER,

           ActiveMQConnection.DEFAULT_PASSWORD,

           "tcp://192.168.0.59:61616");

      //从工厂得到连接对象

      connection =connectionFactory.createConnection();

      //启动

      connection.start();

      //获取操作连接

      session =connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

      //创建目的地队列

      destination =session.createQueue("SecondQueue");

      //创建消息接收者

      consumer =session.createConsumer(destination);

      while(true){

         TextMessage message =(TextMessage)consumer.receive(500000);

         if(null != message){

           logger.info("收到消息" + message.getText());

         }else{

           break;

         }

      }

   } catch (Exception e) {

      logger.error(e.getMessage(), e);

   } finally {

      if(null != connection){

         try {

           connection.close();

         } catch (Exception e) {

           logger.error(e.getMessage(),e);

         }

      }

   }

}

}

 

3、先启动consumer代码等待producer的到来,然后启动producer代码来接收消息

0 0
原创粉丝点击