ActiveMQ系列(四)ActiveMQ核心功能持久化、事務、簽收

本文總結下ActiveMQ的核心功能,涉及一些概念和API。

一. Jms生產者Demo

先上一個生產者的小demo,然後圍繞demo展開:

import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

public class JmsProduce {
    public static final String ACTIVEMQ_URL = "tcp://192.168.17.101:61616";
    public static final String QUEUE_NAME = "queue01";

    public static void main(String[] args) throws JMSException {
        //創建連接工廠,按照給定的url地址,使用默認用戶名和密碼
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //通過連接工廠獲取連接,並啓動
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();

        //創建會話session,true開啓事務,false不開啓事務
        Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
        //創建目的地,是隊列還是topic
        Queue queue = session.createQueue(QUEUE_NAME);
        //創建消息的生產者
        MessageProducer producer = session.createProducer(queue);
        //持久化模式設置
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        
        try {
            //生產3條消息到隊列
            for (int i = 1; i <= 3; i++) {
                //創建消息
                TextMessage textMessage = session.createTextMessage("msg--" + i);
                //使用生產者發送消息
                producer.send(textMessage);
            }
            session.commit();
        } catch (JMSException e) {
        	//異常情況回滾提交
            session.rollback();
        } finally {
            //關閉資源
            producer.close();
            //如果上邊開啓事務,那麼這裏要提交,不然消息不進入隊列

            session.close();
            connection.close();
        }

        System.out.println("發佈消息到隊列完成!");
    }
}

上述是ActiveMQ的一種生產者的原生標準實現,生產3個消息到隊列Queue中(或者主題Topic中),並且使用了事務模式。

本demo使用了JMS包,下面先總結下JMS。

二. JMS介紹

1.jms是什麼

上述demo中使用了javax.jms.包中的內容,比如Connection/Session/Queue/MessageProducer/TextMessage等。JMS(Java Message Service),java消息服務,是JavaEE規範中的一個模塊,制定了消息接收發送的一套標準規範,其中落地產品有很多(各種MQ),ActiveMQ就是其中一款落地產品,它完全遵守了JMS規範。

JMS提供了一套API,爲標準消息協議和消息服務提供了一組接口,包括創建,發送,讀取消息等。

2.jms組成的四大元素

  • jms peovider :實現jms接口和規範的消息中間件,也就是MQ服務器;
  • jms producer :消息生產者,創建和發送jms消息的客戶端應用;
  • jms consumer :消息消費者,接收和處理jms消息的客戶端應用;
  • jms message :發送和被接受的消息,包含消息頭,消息體,消息屬性;

在這裏插入圖片描述

3.jms 消息頭
列舉幾個比較重要參數:

  • JMSDestination :消息發送的目的地,主要指Queue還是Topic;Message接口提供了setJMSDestination方法;
  • JMSDeliveryMode :設置持久化或者非持久化模式,非持久化模式下,MQ宕機,消息丟失,但是持久化模式不會丟失;
  • JMSExpiration :設置消息過期時間,過期後會清除,默認是永不過期;
  • JMSPriority :消息優先級,包含0-9是個級別,0-4是普通消息,5-9是加急消息,默認是4。JMS規範不要求MQ嚴格按照這個優先級順序發送,但是要保證5-9的早於0-4的。
  • JMSMessageID :唯一識別每個消息的標識,由MQ產生或者自己設定;

以上參數可以針對每條消息單獨設置,也可以在send方法中統一設置。

4.消息體
消息體封裝具體的消息數據,有多種類型格式,消息發送方和接收方的格式必須保持一致。
5種消息體格式:

  • TextMessage :普通字符串,包含一個string;
  • MapMessage :map類型,其中key爲String類型,
  • BytesMessage :二進制數組消息,包含一個byte[];
  • StreamMessage :java數據流消息,用標準流來順序填充和讀取;
  • ObjectMessage :對象消息,包含一個可序列話的java對象;

5.消息屬性
識別,去重,重點標註等操作。
接口方法:
setStringProperty(String name, String value);
除此之外,還有setIntProperty等類型;需要注意的是,生產者與消費者的類型要保持一致。

三. 消息的持久化

jms消息默認是持久化的,可以通過JMS接口的如下方法設置持久與非持久:

void setDeliveryMode(int deliveryMode) throws JMSException;

public interface DeliveryMode {
	//非持久
    static final int NON_PERSISTENT = 1;
	//持久
    static final int PERSISTENT = 2;
}

非持久模式下,MQ如果宕機再啓動,消息會丟失;持久化模式下,消息只要沒消費掉,不會丟失。

四. 消息事務

1.生產者事務

文章開頭的demo中,有如下內容:

//創建會話session,true開啓事務,false不開啓事務
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

第一個參數,true表示開啓事務;false表示關閉事務;

開啓了事務模式,那麼就需要提交事務:
session.commit();
提交事務之前,消息不進入隊列;只有提交後,消息才進入隊列,消費者才能消費到。

2.消費者事務
消費者的事務使用代碼和生產者一樣。
消費者中,要注意commit,否則消費者會重複消費消息,消息一直在隊列中消費不掉;只有提交事務後,才能被消費掉。

五. 消息簽收

簽收針對的是消費者,在消費者中,一般也會有如下代碼:

//創建會話session,true開啓事務,false不開啓事務
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

其中,第二個參數是簽收模式。在非事務模式下,共有如下幾種類型:

  • Session.AUTO_ACKNOWLEDGE = 1; //自動簽收,默認就是這種方式;在這種模式下,消費者會自動簽收消息,也就是在拿到消息時,就默認簽收了,不用在調用方法進行簽收;

  • Session.CLIENT_ACKNOWLEDGE = 2; //手動簽收,在這種模式下,消費者拿到消息後,需要使用如下方法進行手動簽收,
    textMessage.acknowledge ();
    ,否則,消息會殘留在消息隊列中,導致重複消費。

  • Session.DUPS_OK_ACKNOWLEDGE = 3; //允許重複簽收,這種模式基本不使用。

注意,上述模式是針對非事務模式的;
如果在事務模式下,那麼簽收模式會失效,即使配置的是手動簽收,在事務模式下,也會被自動簽收。

六.傳輸協議種類

Demo中,使用瞭如下連接,可以發現,使用的的是tcp協議,

 public static final String ACTIVEMQ_URL = "tcp://192.168.17.101:61616";

除了此種協議,ActiveMQ還支持其他類型協議:

1.transmission Control Protocol(TCP)

tcp是默認使用的協議,端口61616;
使用格式:tcp://hostname:port?key=value ,key和value可以不添加,具體內容有:
在這裏插入圖片描述
全部內容看官方文檔:
http://activemq.apache.org/tcp-transport-reference

2.New I/O API Protocol (NIO)

nio基於tcp協議,進行了擴展和優化,比tcp協議具有更好的性能,實際生產中,也大多使用此種協議。
要使用此種模式,需要修改ActiveMQ的配置文件:conf / activemq.xml ,增加

<transportConnector name="nio" uri="nio://0.0.0.0:61616"/>  

在這裏插入圖片描述
使用格式:nio://hostname:port?key=value ,其中key和value同tcp配置。

具體參考官方文檔:
http://activemq.apache.org/configuring-version-5-transports.html

auto模式
從5.13.0版本開始,activemaq支持auto自動模式,可以從多種類型的協議中自動探測最終使用哪種協議。
在這裏插入圖片描述
官方文檔:http://activemq.apache.org/auto

3.AMQP 協議
4.stomp協議
5.Secure Sockets Layer Protocol (SSL)安全連接
6. mqtt 協議
7. ws 協議

上述其他協議使用不多,具體看官方文檔:

http://activemq.apache.org/configuring-version-5-transports.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章