public class TopicPersistentTest {
//編寫消息的發送端-----生產者
@Test
public void test1() throws Exception{
//創建鏈接工廠對象
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
//從工廠中獲取一個鏈接對象
Connection connection = connectionFactory.createConnection();
//獲取session對象
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//通過session對象創建主題
Topic topic = session.createTopic("topic");
//通過session對象創建消息的發送者
MessageProducer producer = session.createProducer(topic);
//開啓持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//連接MQ服務
connection.start();
//通過session創建消息對象
TextMessage message = session.createTextMessage("ping");
//發送消息
producer.send(message, DeliveryMode.PERSISTENT, 1, 1000*60*60*24);
//關閉相關資源
producer.close();
session.close();
connection.close();
}
//編寫消息的接收端-----消費者
@Test
public void test2() throws Exception{
//創建鏈接工廠對象
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
//從工廠中獲取一個鏈接對象
Connection connection = connectionFactory.createConnection();
//設置客戶端id
connection.setClientID("client-1");
//連接MQ服務
connection.start();
//獲取session對象
final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//通過session對象創建主題
Topic topic = session.createTopic("topic");
//通過session對象創建消息的消費者
// MessageConsumer consumer = session.createConsumer(topic);
//設置主體的訂閱者
TopicSubscriber consumer = session.createDurableSubscriber(topic, "client1-sub");
//指定消息監聽器1
consumer.setMessageListener(new MessageListener() {
//當監聽的topic中存在消息,這個方法自動執行
public void onMessage(Message message) {
if (null != message && message instanceof TextMessage){
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("消費者接收到了消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
while(true) {
}
}
}
總結:
- 在使用Topic主題處理消息時,消費者必須先訂閱主題,消費者不能接收到主題訂閱之前產生的消息
- 在獲取Session對象時如果事務設置爲true,則需要調用commit方法提交事務
- 在獲取Session對象時如果開啓手動簽收,必須調用acknowledge方法手動簽收,否則消息不會被消費
- 如果開啓事務,則會強制自動簽收,即當事務被成功提交則消息被自動簽收,如果事務回滾,則消息會被再次傳送。創建Session對象的第二個簽收參數無效
- 生產者開啓持久化後,服務器宕機後重啓服務器,消費者也能接收到宕機前發送的消息,關閉持久化之後則不能接收到宕機前的消息。默認開啓了持久化
- 非持久訂閱只有當消費者與MQ保持連接狀態才能接收到發送到某個主題的消息,如果消費者處於離線狀態,生產者發送的主題消息將會丟失,消費者不會接收到
- 持久訂閱:客戶端首先向MQ註冊一個自己的身份ID識別號,當這個客戶端處於離線時,生成者會爲這個ID保存所有發送到主題的消息,當消費者再次連接到MQ時會根據消費者的ID得到所有當自己處於離線狀態時發送到主題的消息
- 非持久訂閱狀態下,不能恢復或重新派送一個未簽收的消息
- 持久訂閱狀態下才能恢復或重新派送一個未簽收的消息