订阅(主题)消息(消息持久化)
demo下载地址(http://download.csdn.net/detail/qq_29582193/9917464)
环境搭建请参看上一篇文章《activeMQ环境搭建详解》http://blog.csdn.net/qq_29582193/article/details/76448415
管理后台探究
-
网页打开http://127.0.0.1:8161/
输入默认的用户名密码 admin/admin
-
进入后可以看到消息监控页面
-
订阅者详情页面解释
初步了解了后台监控现在开始撸代码
-
代码结构 普通消息已经在上一节说过了这里就不再赘述(待更新)
-
代码清单(由于订阅者中差别就只是一个id和一个name不同这里只贴出一份)
TopicPublisher.java
package com.lcd.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
* 订阅消息
* @author Administrator
*
*/
public class TopicPublisher {
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER; //默认的连接用户名
private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD; //默认的连接密码
private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL; //默认的连接地址
private static final int SENDNUM = 10; //发送的消息数量
public static void main(String[] args) {
ConnectionFactory connectionFactory; //连接工厂
Connection connection = null; //连接
Session session; //会话 接受或者发送消息的线程
Destination destination; //消息的目的地
MessageProducer messageProducer; //消息生产者
//实例化连接工厂
connectionFactory = new ActiveMQConnectionFactory(TopicPublisher.USERNAME, TopicPublisher.PASSWORD,
TopicPublisher.BROKEURL);
try {
connection = connectionFactory.createConnection(); // 通过连接工厂获取连接
connection.start(); //启动连接
session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // 创建Session
// destination=session.createQueue("FirstQueue1"); // 创建消息队列
destination = session.createTopic("FirstTopic1");
messageProducer = session.createProducer(destination); // 创建消息生产者
sendMessage(session, messageProducer); //发送消息
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
*发送消息
*
* @param session
* @param messageProducer
* @throws Exception
*/
public static void sendMessage(Session session, MessageProducer messageProducer) throws Exception {
for (int i = 0; i < TopicPublisher.SENDNUM; i++) {
TextMessage message = session.createTextMessage("ActiveMQ发送的消息" + i);
System.out.println("发送消息:" + "ActiveMQ 发布的消息" + i);
messageProducer.send(message);
}
}
}
订阅者
TopicSubscriber.java
package com.lcd.activemq;
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 javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TopicSubscriber {
private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; //默认的连接用户名
private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; //默认的连接密码
private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; //默认的连接地址
public static void main(String[] args) {
ConnectionFactory connectionFactory; //连接工厂
Connection connection = null; //连接
Session session; // 会话 接受或者发送消息的线程
Topic topic; // 消息的目的地
MessageConsumer messageConsumer; //消息的消费者
// 实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(TopicSubscriber.USERNAME, TopicSubscriber.PASSWORD, TopicSubscriber.BROKEURL);
try {
connection=connectionFactory.createConnection(); //通过连接工厂获取连接
connection.setClientID("2"); //持久订阅需要设置这个订阅id
connection.start(); // 启动连接
session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); //创建Session
// destination=session.createQueue("FirstQueue1"); //创建连接的消息队列
topic =session.createTopic("FirstTopic1");
//messageConsumer=session.createConsumer(destination); //创建消息消费者
//这里的121是Subscription Name可以和id不同
messageConsumer = session.createDurableSubscriber(topic,"我的名字是1"); //持久订阅
messageConsumer.setMessageListener(new Listener()); //注册消息监听
} catch (JMSException e) {
e.printStackTrace();
}
}
}
订阅者监听
Listener.java
package com.lcd.activemq;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class Listener implements MessageListener {
public void onMessage(Message message) {
try {
System.out.println("订阅者一收到的消息:"+((TextMessage)message).getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
运行测试
后台:因为我还没有启动订阅者所以有10条消息还没有出队列 没有消费
启动订阅者1:成功消费消息
后台变化:id=1的已经推送所有消息2的还有10条消息未推送
后续:
常见异常
1、消息无法订阅接收
原因:推送者无session.commit();消息未提交到服务器 、订阅者没有第一次启动注册到服务器
2、同时启动连个id一样的订阅者报错与名字无关
log4j:WARN No appenders could be found for logger (org.apache.activemq.thread.TaskRunnerFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
javax.jms.InvalidClientIDException: Broker: localhost - Client: 1 already connected from tcp://127.0.0.1:52650
at org.apache.activemq.broker.region.RegionBroker.addConnection(RegionBroker.java:255)
at org.apache.activemq.broker.jmx.ManagedRegionBroker.addConnection(ManagedRegionBroker.java:230)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.advisory.AdvisoryBroker.addConnection(AdvisoryBroker.java:116)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:98)
at org.apache.activemq.broker.MutableBrokerFilter.addConnection(MutableBrokerFilter.java:103)
at org.apache.activemq.broker.TransportConnection.processAddConnection(TransportConnection.java:818)
at org.apache.activemq.broker.jmx.ManagedTransportConnection.processAddConnection(ManagedTransportConnection.java:77)
at org.apache.activemq.command.ConnectionInfo.visit(ConnectionInfo.java:139)
at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:339)
at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:188)
at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:125)
at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:300)
at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
at java.lang.Thread.run(Thread.java:745)
demo下载地址(http://download.csdn.net/detail/qq_29582193/9917464)
环境搭建请参看《activeMQ环境搭建详解》http://blog.csdn.net/qq_29582193/article/details/76448415