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方法