最近在学习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();
}
}
}
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个订阅者都成功收到了消息...