ActiveMQ--Topic模式

Topic Subsriber模式

訂閱模式分爲非持久訂閱(Non-Durable Topic Subscribers)和持久訂閱模式(Durable Topic Subscribers)

非持久訂閱(Non-Durable Topic Subscribers)

  • 生產者生產消息,誰訂閱,誰就會收到
  • 生產者生產消息,沒有人訂閱,消息廢棄,當consumer啓動連接時,廢棄的消息不會再次被收到

代碼如下:

package com.pgy.jms.sub;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Date: Created in 27/12/2017 1:01 PM
 * @Author: pengganyu
 * @Desc:
 */

public class Producer {

    public static void main(String[] args) throws JMSException, InterruptedException {
        ConnectionFactory factory = new ActiveMQConnectionFactory(
            ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD,
            ActiveMQConnectionFactory.DEFAULT_BROKER_URL);

        Connection connection = factory.createConnection();
        connection.start();

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

        Topic topic = session.createTopic("hello");

        MessageProducer producer = session.createProducer(topic);

        int i = 0;
        while (true) {
            Thread.sleep(3000);
            producer.send(session.createTextMessage("hello" + i++));
        }
    }
}
package com.pgy.jms.sub;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Date: Created in 27/12/2017 2:19 PM
 * @Author: pengganyu
 * @Desc:
 */

public class Cousmer {

    public static void main(String[] args) throws JMSException {
        TopicConnectionFactory factory = new ActiveMQConnectionFactory(
            ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD,
            ActiveMQConnectionFactory.DEFAULT_BROKER_URL);

        Connection connection = factory.createTopicConnection();
        connection.start();

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

        Topic topic = session.createTopic("hello");

        MessageConsumer consumer = session.createConsumer(topic);

        //        consumer.setMessageListener(message -> System.out.println(message));

        while (true) {
            TextMessage textMessage = (TextMessage) consumer.receive();
            System.out.println(textMessage.getText());

        }

    }
}

說明

  • 生產者在不停地生產消息,如果消費者不啓動,消費者是無法接收到消息的;(運行Producer)
  • 消費者啓動連接後,之前的消息是不會被接收到,啓動後纔可以接收到當前生產出來的消息(運行Consumer)
  • 消費者斷開連接後,無法接收到生產者生產的消息(停止consumer)
  • 消費者再次連接後,之前丟失的消息無法繼續再收到,只能接收到當前生產出來的消息(啓動consumer)

持久訂閱(Durable Topic Subscribers)

生產者的代碼與非持久的相同,consumer的代碼如下

package com.pgy.jms.sub;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Date: Created in 27/12/2017 2:19 PM
 * @Author: pengganyu
 * @Desc:
 */

public class Cousmer1 {

    public static void main(String[] args) throws JMSException {
        TopicConnectionFactory factory = new ActiveMQConnectionFactory(
            ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD,
            ActiveMQConnectionFactory.DEFAULT_BROKER_URL);

        Connection connection = factory.createTopicConnection();
        connection.setClientID("consumer1");
        connection.start();

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

        Topic topic = session.createTopic("hello");

        MessageConsumer consumer = session.createDurableSubscriber(topic, "consumer1");


        //        consumer.setMessageListener(message -> System.out.println(message));

        while (true) {
            TextMessage textMessage = (TextMessage) consumer.receive();
            System.out.println(textMessage.getText());

        }

    }
}
package com.pgy.jms.sub;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Date: Created in 27/12/2017 2:19 PM
 * @Author: pengganyu
 * @Desc:
 */

public class Cousmer2 {

    public static void main(String[] args) throws JMSException {
        TopicConnectionFactory factory = new ActiveMQConnectionFactory(
            ActiveMQConnectionFactory.DEFAULT_USER, ActiveMQConnectionFactory.DEFAULT_PASSWORD,
            ActiveMQConnectionFactory.DEFAULT_BROKER_URL);

        Connection connection = factory.createTopicConnection();
        // 與非持久訂閱相比,需要設置ClientID
        connection.setClientID("consumer2");
        connection.start();

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

        Topic topic = session.createTopic("hello");
        // 與非持久訂閱相比,需要用持久訂閱方法去創建消費者
        MessageConsumer consumer = session.createDurableSubscriber(topic, "consumer2");

        while (true) {
            TextMessage textMessage = (TextMessage) consumer.receive();

            System.out.println(textMessage.getText());

        }

    }
}

說明

  • 生產者在不停地生產消息,此時若沒有人訂閱,消息直接廢棄(啓動Producer)
  • 消費者1啓動,無法接收到之前Producer生產的消息,只能接收到當前的消息(啓動Consumer1)
  • 消費者2啓動,也無法接收之前Producer生產的消息,只能接收到當前的消息(啓動Consumer2)
  • 中斷消費者2,消費者1繼續接收消息,消費者2無法接收消息(停止Consumer2)
  • 啓動消費者2,消費者1繼續接收消息,消費者2可以接收到之前停止後丟失的消息,並可以繼續接收當前消息(啓動Consumer2)
  • ActiveMQ是通過ClientID判斷消息是否已經發給連接點,若消費者的ClientID相同,那麼只會被某一個消費者接收到消息,而另外一個會報錯
  • 與非持久訂閱模式的區別僅爲設置了ClinetID及創建消費者使用createDurableSubscriber方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章