ActiveMQ案例——Queue隊列(點對點模式)

public class QueueTest {
    //編寫消息的發送端-----生產者
    @Test
    public void test1() throws Exception{
        //創建鏈接工廠對象
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        //從工廠中獲取一個鏈接對象
        Connection connection = connectionFactory.createConnection();
         //獲取session對象  第一個參數爲事務,第二個參數爲簽收
        //如果事務設置爲true,則需要調用commit方法提交事務
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //通過session對象創建目的地(主題/隊列)
        Destination destination = session.createQueue("queue");
        //通過session對象創建消息的發送者(生產者)
        MessageProducer producer = session.createProducer(destination);
         //開啓持久化
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        //連接MQ服務
        connection.start();
    
        //通過session創建消息對象
        TextMessage message = session.createTextMessage("ping");
        //設置消息屬性
        message.setStringProperty("c01", "vip");
        //MapMessage消息對象
        MapMessage mapMessage = session.createMapMessage();
        mapMessage.setString("key", "value");
        //設置消息是否持久化  默認開啓了持久化
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

        //發送消息
        producer.send(message);
        producer.send(mapMessage);
        //關閉相關資源
        producer.close();
        session.close();
        connection.close();
    }

    //編寫消息的接收端-----消費者
    @Test
    public void test2() throws Exception{
        //創建鏈接工廠對象
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        //從工廠中獲取一個鏈接對象
        Connection connection = connectionFactory.createConnection();
        //連接MQ服務
        connection.start();
       //獲取session對象 開啓手動簽收後 必須調用acknowledge方法手動簽收,否則消息不會被消費
        //如果開啓事務,則會強制自動簽收
        final Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
        //通過session對象創建目的地(主題/隊列)
        Destination destination = session.createQueue("queue");
        //通過session對象創建消息的消費者
        MessageConsumer consumer = session.createConsumer(destination);
        //指定消息監聽器
        consumer.setMessageListener(new MessageListener() {
            //當監聽的queue中存在消息,這個方法自動執行
            public void onMessage(Message message) {
                if (null != message && message instanceof TextMessage){
                    TextMessage textMessage = (TextMessage) message;
                    try {
                        System.out.println("消費者接收到了textMessage消息:" + textMessage.getText());
                        System.out.println("消費者接收到了消息屬性:" + textMessage.getStringProperty("c01"));
                        //客戶端手動確認簽收
                        message.acknowledge();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (null != message && message instanceof MapMessage){
                    MapMessage mapMessage = (MapMessage) message;
                    try {
                        System.out.println("消費者接收到了mapMessage消息:" + mapMessage.getString("key"));
                        //客戶端手動確認
                      message.acknowledge();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        while(true) {

        }
    }
}

總結:

  1. 在使用Queue隊列處理消息時,無論消費者在消息產生前和產生後開啓,消息都能夠接收到,即消費者開啓前的消息不會丟失
  2. 在獲取Session對象時如果事務設置爲true,則需要調用commit方法提交事務
  3. 在獲取Session對象時如果開啓手動簽收,必須調用acknowledge方法手動簽收,否則消息不會被消費
  4. 如果開啓事務,則會強制自動簽收,即當事務被成功提交則消息被自動簽收,如果事務回滾,則消息會被再次傳送。創建Session對象的第二個簽收參數無效
  5. 如果在Session關閉時有消息已被接收到但還沒有被簽收,那當消費者下次連接到相同的隊列時,這些消息還會被再次接受
  6. 生產者開啓持久化後,服務器宕機後重啓服務器,消費者也能接收到宕機前發送的消息,關閉持久化之後則不能接收到宕機前的消息。默認開啓了持久化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章