ActiveMQ系列之——安装、运行及事例代码(一)

写在前面的话

ActiveMQ在去年做项目时使用过,当时为了进度,急急忙忙的,木有太多的时间对ActiveMQ深入的了解,只了解其基本的用法,当时和Spring集成,木有做持久化的工作,现在有时间,重新整理、总结、归档一些知识,做点记录

前期准备

Linux:CentOS 32位。

ActiveMQ:5.9.0,下载地址:http://activemq.apache.org/download.html

说明:我是在Windows上面做开发,IDE为Eclipse,Maven为构建工具,使用CentOS的虚拟机,IP地址为:192.168.254.150,root帐户,若不使用root帐户,可以自行创建其它用记,并分配权限,然后再安装ActiveMQ,此外,要安装JDK,并修改/etc/hosts文件,将主机名与IP地址对应起来,以免在启动ActiveMQ时报“未知的名称和服务”异常。关掉Linux的防火墙,若不关闭,保证在Windows通过Ping命令Ping通Linux即可。

安装

通过以下命令解压ActiveMQ包,tar –zxvf apache-activemq-5.9.0-linux-bin.tar.gz,安装目录即为当前目录。安装之前要先保证系统中已经安装了JDK,具体可参考我的博客中关于Linux安装JDK的文章。

注:我使用root帐户,所以木有创建用户、目录及授权的过程,若使用其它用户,需要授权等操作。

运行

启动ActiveMQ有几种方式,版本不同,略有区别,我使用的是5.9,启动方式有所变化,以前在使用旧版本时,直接运行bin/activemq命令即可,但在5.9下不行,可以看其提示,如下:

[root@wds activemq-5.9.0]# bin/activemq
…
…
Usage: Main [--extdir <dir>] [task] [task-options] [task data]

Tasks:
browse  - Display selected messages in a specified destination.
bstat  - Performs a predefined query that displays useful statistics regarding the specified broker
create  - Creates a runnable broker instance in the specified path.
decrypt    - Decrypts given text
dstat   Performs a predefined query that displays useful tabular statistics regarding the specified destination type
encrypt  - Encrypts given text
export  - Exports a stopped brokers data files to an archive file
list  - Lists all available brokers in the specified JMX context
purge   - Delete selected destination's messages that matches the message selector
query  - Display selected broker component's attributes and statistics.
start   - Creates and starts a broker using a configuration file, or a broker URI.
stop  - Stops a running broker specified by the broker name.
…
…

通过该命令的提示,就可知其用法,我使用两种方式启动,在介绍这两种方式之前,先看下我的目录结构,如下图:


第一种方式:bin/activemq start,执行结果如下:


第二种方式:bin/activemq console,如下图:


关于console的说明,可输入bin/activemq,给出的说明中就有关于console的介绍,其它的启动方式木有一一去尝试,官方给出的一种还nohup的方式。

验证与关闭

通过以下命令查看ps –ef | grep activemq,如下图所示:


看其前面的进程号,3110,可通过kill -9 3110的方式将其关闭。如果是第二种方式启动的,直接按Ctrl+C键关闭。

注意配置好ActiveMQ后,前几次都启动成功。有一天启动时发现启动不成功,查看报错日志发现出现如下提示:

  1. Failed to startApache ActiveMQ (localhost, ID:*-PC-*-*-0:1). Reason: java.io.IOException:Transport Connector could not be registered in JMX: Failed to bind to serversocket:tcp://0.0.0.0:61616?maximumConnections=1000&wireformat.maxFrameSize=104857600due to: java.net.BindException: Address already in use: JVM_Bind
  2. 先去查看是不是端口被占用,用netstat -ano命令查看端口使用情况,发现没有端口被占用。
  3. 在控制面板的服务里把正在运行的不确定的服务都关了。发现是Internet Connection Sharing (ICS)为家庭和小型办公网络提供网络地址转换、寻址、名称解析和/或入侵保护服务。
  4. 把此服务关了后再启动ActvieMQ成功了。
  5. 我的情况是:使用VM虚拟机,通过NAT的方式连接外网,在公司我使用的有线连接,在家使用的无线连接,通过NAT的方式上网,需要将本地有线或无线连接设置成共享的方式,但是由于在公司和在家使用的连接方式不同,导致ActiveMQ启动不成功。

基本管理

ActiveMQ提供了两种方式,监控MQ,分别是 http://localhost:8161/adminhttp://localhost:8161/hawtio,这两个地址都可以查看ActiveMQ的运行情况,这里不做过多介绍。
ActiveMQ的主要配置都在conf目录,其中最常用的就是activemq.xml文件,该文件类似Spring的配置文件,有加载外部属性文件、定义Bean,日志的配置也在此目录下,当然关于权限等其它配置也是在此目录下的,目录下有log4j.properties的配置,可以修改日志级别观察ActiveMQ的运行情况。

示例代码

示例代码只是基本的Queue和Topic的代码,木有与Spring集成(这一部分后续会写),代码主要是为后续的运行做准备的,代码非常简单,就是接发消息。

JMS规范定了两种类型的消息,一是点对点的Point-To-Point方式,另一种是发布-订阅的Publish and Subscribe模式。创建一个简单的JMS应用,一般可遵循以下步骤:

1)       获得一个JMS连接工厂。

2)       使用工厂创建JMS连接。

3)       启动连接。

4)       从连接中创建Session。

5)       获得JMS的Destination。

6)       创建JMS消息生产者或创建JMS消息并指向到Destination。

7)       创建JMS消费者或注册监听器

8)       发送或接受JMS消息

9)       关闭JMS资源


Queue

Producer
public class Producer {
	
	private static final Logger logger = LoggerFactory.getLogger(Producer.class);
	
	/**
	 * 定义连接地址,TCP协议,IP为:192.168.254.150,端口:61616
	 */
	private final static String brokerURL = "tcp://192.168.254.150:61616";
	
	/**
	 * 定义连接工厂
	 */
	private static transient ConnectionFactory factory;
	
	/**
	 * 定义连接
	 */
	private transient Connection connection;
	
	/**
	 * 定义Session
	 */
	private transient Session session;
	
	/**
	 * 定义Producer
	 */
	private transient MessageProducer producer;
	
	private String[] queueTitles = new String[]{"QueueOne", "QueueTwo"};
	private static int index = 10;
	
	/**
	 * 初始化上述的几个属性
	 * @throws JMSException
	 */
	public Producer() throws JMSException {
		factory = new ActiveMQConnectionFactory(brokerURL);
		connection = factory.createConnection();
		connection.start();
		session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		producer = session.createProducer(null);
	}
	

	public static void main(String[] args) throws JMSException {
		Producer producer = new Producer();
		int i = 0;
		while(i < 10){
			producer.sendMsg(i);
			i++;
		}
		producer.close();
	}
	
	public void close(){
		try {
			this.connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void sendMsg(int serial) throws JMSException {
		int idx = 0;
		while (true) {
			idx = (int) Math.round(queueTitles.length * Math.random());
			if (idx < queueTitles.length) {
				break;
			}
		}
		String title = queueTitles[idx];
		Destination destination = session.createQueue("Queue." + title);
		for(int i = 0; i < index; i++){
			Message message = session.createObjectMessage(title + ", Serial" + serial + ", index" + i);
			logger.info("Sending: id: " + ((ObjectMessage) message).getObject() + " on queue: " + destination);
			producer.send(destination, message);
		}
	}
	

}
Listener
public class Listener implements MessageListener {
	private static final Logger logger = LoggerFactory.getLogger(Listener.class);
	
	public void onMessage(Message message) {
		try {
			logger.info("Consumer:" + ((ObjectMessage)message).getObject());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
Consumer
package com.wds.activemq.sec2.p2p;

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 org.apache.activemq.ActiveMQConnectionFactory;

public class Consumer {
	private final static String brokerURL = "tcp://127.0.0.1:61616";
	private static transient ConnectionFactory factory;
	private transient Connection connection;
	private transient Session session;
	
	private String[] queueTitles = new String[]{"QueueOne", "QueueTwo"};
	
	public Consumer() throws JMSException {
		factory = new ActiveMQConnectionFactory(brokerURL);
		connection = factory.createConnection();
		connection.start();
		session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
	}

	public static void main(String[] args) throws JMSException {
		Consumer consumer = new Consumer();
		for(String qName : consumer.queueTitles){
			Destination destination = consumer.getSession().createQueue("Queue." + qName);
			MessageConsumer msgConsumer = consumer.getSession().createConsumer(destination);
			msgConsumer.setMessageListener(new Listener());
		}
	}
	
	public void close(){
		try {
			this.connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public Session getSession() {
		return session;
	}

}

Topic

Publisher
public class Publisher {

	private static final Logger logger = LoggerFactory.getLogger(Publisher.class);
	
	private final static String brokerURL = "tcp://192.168.254.150:61616";
	private static transient ConnectionFactory factory;
	private transient Connection connection;
	private transient Session session;
	private transient MessageProducer producer;
	
	private String[] topicTitles = new String[]{"TopicOne", "TopicTwo"};
	private static int index = 10;
	
	
	public Publisher() throws JMSException {
		factory = new ActiveMQConnectionFactory(brokerURL);
		connection = factory.createConnection();
		connection.start();
		session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		producer = session.createProducer(null);
	}
	

	public static void main(String[] args) throws JMSException {
		Publisher publisher = new Publisher();
		int i = 0;
		while(i < 10){
			publisher.sendMsg(i);
			i++;
		}
		publisher.close();
	}
	
	public void close(){
		try {
			this.connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void sendMsg(int serial) throws JMSException {
		int idx = 0;
		while (true) {
			idx = (int) Math.round(topicTitles.length * Math.random());
			if (idx < topicTitles.length) {
				break;
			}
		}
		String title = topicTitles[idx];
		Destination destination = session.createTopic("Topic." + title);
		for(int i = 0; i < index; i++){
			Message message = createMessage(title, serial, i);
			logger.info("Sending:" + title + " Serial:" + serial + " index:" + index + " on topic: " + destination);
			producer.send(destination, message);
		}
	}


	private Message createMessage(String title, int serial, int i) throws JMSException {
		MapMessage mapMsg = session.createMapMessage();
		mapMsg.setString("title", title);
		mapMsg.setInt("Serial", serial);
		mapMsg.setInt("index", i);
		return mapMsg;
	}

}
Listener
public class Listener implements MessageListener {
	
	private static final Logger logger = LoggerFactory.getLogger(Listener.class);

	public void onMessage(Message message) {
		try {
			MapMessage map = (MapMessage)message;
			String title = map.getString("title");
			int serial = map.getInt("serial");
			int index = map.getInt("index");
			logger.info("Consumer:" + title + " Serial:" + serial + " index:" + index);

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

}
Consumer
public class Publisher {

	private static final Logger logger = LoggerFactory.getLogger(Publisher.class);
	
	private final static String brokerURL = "tcp://192.168.254.150:61616";
	private static transient ConnectionFactory factory;
	private transient Connection connection;
	private transient Session session;
	private transient MessageProducer producer;
	
	private String[] topicTitles = new String[]{"TopicOne", "TopicTwo"};
	private static int index = 10;
	
	
	public Publisher() throws JMSException {
		factory = new ActiveMQConnectionFactory(brokerURL);
		connection = factory.createConnection();
		connection.start();
		session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		producer = session.createProducer(null);
	}
	

	public static void main(String[] args) throws JMSException {
		Publisher publisher = new Publisher();
		int i = 0;
		while(i < 10){
			publisher.sendMsg(i);
			i++;
		}
		publisher.close();
	}
	
	public void close(){
		try {
			this.connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		}
	}
	
	public void sendMsg(int serial) throws JMSException {
		int idx = 0;
		while (true) {
			idx = (int) Math.round(topicTitles.length * Math.random());
			if (idx < topicTitles.length) {
				break;
			}
		}
		String title = topicTitles[idx];
		Destination destination = session.createTopic("Topic." + title);
		for(int i = 0; i < index; i++){
			Message message = createMessage(title, serial, i);
			logger.info("Sending:" + title + " Serial:" + serial + " index:" + index + " on topic: " + destination);
			producer.send(destination, message);
		}
	}


	private Message createMessage(String title, int serial, int i) throws JMSException {
		MapMessage mapMsg = session.createMapMessage();
		mapMsg.setString("title", title);
		mapMsg.setInt("Serial", serial);
		mapMsg.setInt("index", i);
		return mapMsg;
	}

}
代码中使用logback作为日志记录,具体可参考博客中关于logback的使用

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值