activeMQ消息详解(续) 订阅(主题)消息(消息持久化)

来源:互联网 发布:数据分析 市场 编辑:程序博客网 时间:2024/06/07 16:34


订阅(主题)消息(消息持久化)

demo下载地址(http://download.csdn.net/detail/qq_29582193/9917464)

环境搭建请参看上一篇文章activeMQ环境搭建详解http://blog.csdn.net/qq_29582193/article/details/76448415

管理后台探究 

  1. 网页打开http://127.0.0.1:8161/

    输入默认的用户名密码 admin/admin

     

  2. 进入后可以看到消息监控页面

     

     

  3. 订阅者详情页面解释

     

    初步了解了后台监控现在开始撸代码

  1. 代码结构  普通消息已经在上一节说过了这里就不再赘述(待更新)

     

  2. 代码清单(由于订阅者中差别就只是一个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); //创建消息消费者

            

            //这里的121Subscription 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