ActivateMQ安装以及使用

最近在学习activeMQ, activeMQ是一个开源的消息插件, 主要功能就是让消费者获取生产者产生的消息


今天就从基础开始,安装以及HelloWorld来了解这个高大上的东西

本文是在linux下安装activeMQ,若在windows下安装,

请参照官方文档:http://activemq.apache.org/getting-started.html#GettingStarted-InstallationProcedureforWindows


1. 获取安装包

wget http://mirrors.cnnic.cn/apache/activemq/5.10.0/apache-activemq-5.10.0-bin.tar.gz

2. 解压缩

tar -zxvf apache-activemq-5.10.0-bin.tar.gz

3. 查看[activemq_install_dir]/bin/activemq 是否有可执行权限

activemq_install_dir就是刚解压的目录, 若没权限则添加执行权限: chmod +x activemq


4。启动

我下载的是5.10.0, 使用./activemq start启动,另外使用start方式启动activemq也不会有断开ssh终端activemq就自动结束的问题,所以无需使用nohup来启动activemq了

ActiveMQ启动方式:

1) ./activemq 使用默认配置Broker配置启动,默认配置文件位置在[activemq_install_dir]/conf/activemq.xml

2) ./activemq xbean:myconfig.xml 使用自定义Broker配置文件启动, 文件名为myconfig.xml, 路径在classpath下

3) ./activemq xbean:file:[文件相对路径/绝对路径] 此种方式可以指定文件路径来启动

4) ./activemq broker:(tcp://localhost:61616, tcp://localhost:5000)?useJmx=true 指定broker的URI来启动


5. 验证是否启动成功

可以查看是否有activemq的进程ps -ef | grep activemq

也可查看默认端口61616是否启动即可(若启动activemq时更改了默认端口,则查看对应端口是否打开)netstat -an | grep 61616


6. 监控activemq状态

若启动activemq成功,则可直接打开浏览器http://localhost:8161/admin来查看, 

从5.8开始,打开监控网站需要密码确认,用户名密码默认都是admin/admin


7. 结束activemq

5.10.0也可以使用./activemq stop来停止服务

当然也可以用杀进程的方式,先用ps -ef | grep activemq找出其进程号pid

然后kill pid即可


######################################

安装成功之后,可以写个HelloWord来测试,activemq的下载文件里,原本就包含有测试用例,

此处我们自己来写,传递消息使用P2P模式queue(另外还有发布订阅模式topic),先创建一个类来产生消息,开始之前需要把activemq-all-5.10.0.jar包放到工程的classpath下:

/** 消息生产者 */
public class MessProducer {
	
	private Connection con;
	private Session session;
	private MessageProducer producer;
	
	public MessProducer() throws JMSException {
		//创建连接工厂
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("nio://192.168.9.102:61616");
//		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost"); //若在本机测试,也可以用此种方式
	
		//创建连接
		System.out.println("producer create conntion...");
		con = factory.createConnection();
		//打开连接
		con.start();			
		/**
		 * 用session来管理收发信息
		 * 第一个参数: session是否可以用事务控制
		 * 第二个参数:表示消费者是否要回馈自己已收到消息, 如果session是可以事务控制的话,该条件会被忽略
		 */		
		session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
		//创建队列
		Destination queue = session.createQueue("GOOD_TEST");
		
		//创建消息生产者(这个生产者可以发消息到指定的队列"GOOD_TEST"上
		producer = session.createProducer(queue);
		producer.setDeliveryMode(DeliveryMode.PERSISTENT);
	}
	
	public void createMessage(String text) {
		try {
			TextMessage message = session.createTextMessage(text);
			
			
			System.out.println("start to send message..." + text);
			producer.send(message);
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void close() {
		try {
			session.close();
			con.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
}

在创建一个消费者

/** 消息接收者 */
public class MessConsumer implements ExceptionListener{

	private Connection con;
	private Session session;
	private MessageConsumer consumer;
	
	public MessConsumer () throws JMSException {
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("nio://192.168.9.102:61616");
//		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://localhost");
		System.out.println("consumer create conntion...");
		con = factory.createConnection();
		con.start();
		
		con.setExceptionListener(this);
		
		session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
		//消费者是创建Consumer, 这个consumer可以从指定的队列"GOOD_TEST"中获取消息
		Destination queue = session.createQueue("GOOD_TEST");
		consumer = session.createConsumer(queue);
	}
	
	public void getMessage() {		
		try {
			/**
			 * 阻塞,知道接收到消息,或者时间到期, 或者消费者关闭,如果设置timeout为0的话,该方法会一直阻塞下去
			 */
			System.out.println("consumer ready to receiving...");
			Message message = consumer.receive(200);
			if (message instanceof TextMessage) {
				TextMessage textMessage = (TextMessage) message;
				String text = textMessage.getText();
				System.out.println("received message:" + text);
			} else {
				System.out.println("received message:" + message.toString());
			}
			
			
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void close() {
		try {
			consumer.close();
			session.close();
			con.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	@Override
	public void onException(JMSException arg0) {
		arg0.printStackTrace();
		System.out.println("JMS Exception occured.  Shutting down client[" + arg0.getMessage() + "]");
	}
	

测试类:

	public static void main(String[] args) throws JMSException {
		MessProducer producer = new MessProducer();
		
		MessConsumer consumer = new MessConsumer();	
		producer.createMessage("test");
		producer.createMessage("hello");	
		
		consumer.getMessage();
		consumer.getMessage();		
		
		producer.close();
		consumer.close();
	}


结果:

producer create conntion...
consumer create conntion...
start to send message...test
start to send message...hello
consumer ready to receiving...
received message:test
consumer ready to receiving...
received message:hello

--可以看到  消费者成功的获取到了消息..

##################################

下面再试试用发布订阅的方式来收发消息Topic,Topic和Queue方式差不多,代码如下:

发送者:

public class TopicProducer {

	private Connection con;
	private Session session;
	private MessageProducer producer;
	
	public TopicProducer() {
		try {
			ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("nio://192.168.9.102:61616");
			con = factory.createConnection();
			con.start();
			
			session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);		
			producer = session.createProducer(null);
			producer.setDeliveryMode(DeliveryMode.PERSISTENT);
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void sendTopicMessage() {
		try {
			Destination dest = session.createTopic("GOOD_TOPIC");
			MapMessage message = session.createMapMessage();
			message.setString("name", "andy");
			message.setInt("age", 12);
			message.setInt("sex", 1);
			
			System.out.println("producer send message...");
			producer.send(dest, message);
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void close() {
		try {
			if (producer != null) {
				producer.close();
			}
			if (session != null) {
				session.close();
			}
			if (con != null) {
				con.close();
			}
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
}

接收者,此处采用的是异步接收,即实现MessageListener,当然也可以用步接收,同步接收方式即为上方queue中consumer接受消息的方法,通过receive方法接收
public class TopicConsumer implements MessageListener {

	private Connection con;
	private Session session;
	private MessageConsumer consumer;

	private String consumerName;
	
	public TopicConsumer() {
		try {
			ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(
					"nio://192.168.9.102:61616");
			con = factory.createConnection();
			con.start();

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

		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

	public void getTopicMessage(String consumerName) {
		try {
			Destination destination = session.createTopic("GOOD_TOPIC");
			consumer = session.createConsumer(destination);

			consumer.setMessageListener(this);
			this.consumerName = consumerName; 
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

	public void close() {
		try {
			if (consumer != null) {
				consumer.close();
			}
			if (session != null) {
				session.close();
			}
			if (con != null) {
				con.close();
			}
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void onMessage(Message message) {
		try {
			if (message instanceof MapMessage) {
				MapMessage mapMessage = (MapMessage) message;
				String name = mapMessage.getString("name");
				int age = mapMessage.getInt("age");
				int sex;

				sex = mapMessage.getInt("sex");

				System.out.println(consumerName + "=>get message[name:" + name + ", age:" + age
						+ ",sex:" + sex + "]");
			} else {
				if (message != null) {
					System.out.println("get message[" + message + "]");
				} else {
					System.out.println("get message[null]");
				}
			}
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

测试代码:

	public static void main(String[] args) {		
		TopicConsumer consumer1 = new TopicConsumer();
		consumer1.getTopicMessage("consumer1");
		TopicConsumer consumer4 = new TopicConsumer();
		consumer4.getTopicMessage("consumer4");
		TopicConsumer consumer2 = new TopicConsumer();
		consumer2.getTopicMessage("consumer2");
		TopicConsumer consumer3 = new TopicConsumer();
		consumer3.getTopicMessage("consumer3");
		
		TopicProducer producer = new TopicProducer();
		producer.sendTopicMessage();
		
		Thread t = new Thread(new Runnable() {			
			@Override
			public void run() {
				for (int i=0;i<1000;i++) {
					try {
						System.out.println("main thread waiting...");
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		t.start();
		try {
			t.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		producer.close();
		consumer1.close();
		consumer2.close();
		consumer3.close();
		consumer4.close();
	}


结果如下:

producer send message...
consumer2=>get message[name:andy, age:12,sex:1]
consumer3=>get message[name:andy, age:12,sex:1]
consumer1=>get message[name:andy, age:12,sex:1]
consumer4=>get message[name:andy, age:12,sex:1]
main thread waiting...
main thread waiting...


--可以看到 4个订阅者都成功收到了消息...

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值