1. 程式人生 > >eclipse paho包對於ActiveMQ持久化訂閱者的設定

eclipse paho包對於ActiveMQ持久化訂閱者的設定

在實現基於ActiveMQ的電影推送系統的過程中,因為是Android端的應用程式,而在查閱網上的各種資料發現,Android端直接用原生的MQTT來做推送的比較少,而eclipse paho這個封裝好的API似乎比較好用在Android端的推送上,於是就採用這個包來做。推送的大致流程可以檢視這個網頁:基於paho包的Android demo

將邏輯寫在Service可以使程式在後臺執行時也收到推送。但是有個問題要處理,就是離線的訊息不能丟失,所以要使訊息持久化。而ActiveMQ實現了持久化訂閱者的操作。持久化訂閱者的概念大致如下,也可以去該網址檢視:ActiveMQ持久化訂閱者

ActiveMQ

支援兩種傳輸模式:持久傳輸和非持久傳輸(persistent and non-persistent delivery)。可以通過MessageProducer類的setDeliveryMode方法設定傳輸模式。

持久傳輸和非持久傳輸最大的區別是:採用持久傳輸時,傳輸的訊息會儲存到磁碟中(messages are persisted to disk/database),即“儲存轉發”方式。先把訊息儲存到磁碟中,然後再將訊息“轉發”給訂閱者。

採用非持久傳輸時,傳送的訊息不會儲存到磁碟中。 採用持久傳輸時,當Borker宕機恢復後,訊息還在。採用非持久傳輸,Borker宕機重啟後,訊息丟失。比如,當生產者將訊息投遞給
Broker後,Broker將該訊息儲存到磁碟中,在Broker將訊息傳送給Subscriber之前,Broker宕機了,如果採用持久傳輸,Broker重啟後,從磁碟中讀出訊息再傳遞給Subscriber;如果採用非持久傳輸,這條訊息就丟失了。

ActiveMQ預設的傳輸模式是持久傳輸。對於我們的專案而言,為了保證訊息不丟失,我們專案中也要採用持久傳輸。

接下來介紹持久訂閱者和非持久訂閱者。持久訂閱者和非持久訂閱者針對的是訂閱釋出模式而不是點對點模式。當Broker傳送訊息給訂閱者時,如果訂閱者處於inactive狀態:持久訂閱者可以收到訊息,原理為:持久訂閱時,客戶端向JMS 伺服器註冊一個自己身份的

ID,當這個客戶端處於離線時,JMS Provider 會為這個ID儲存所有傳送到主題的訊息,當客戶再次連線到JMS Provider時,會根據自己的ID得到所有當自己處於離線時傳送到主題的訊息。而非持久訂閱者則收不到訊息。

持久訂閱者/非持久訂閱者,隻影響離線的時候訊息(包括持久訊息和非持久訊息)是否能接收到,和訊息是否持久無關;持久訊息/非持久訊息,只是影響jmsprovider宕機後。訊息是否會丟失,如果永遠不會宕機,那麼持久訊息和非持久訊息沒有區別。

而原生ActiveMQ持久化訂閱者的程式碼網上也比較多,具體可以看這個網址:ActiveMQ持久化訂閱者實現

但基於paho包的實現持久化訂閱者的程式碼沒有在網上查閱到。於是自己仔細研究了下,發現是可以實現的。下面我就來詳細講一下。

是否是持久化訂閱者和兩個地方有關係,首先是連線時連線選項也就是MqttConnectOptions有關,該物件可以設定心跳時間、超時時間等,但和是否是持久化訂閱者有關的則是setCleanSession這個成員方法,它接收的引數是boolean,引數為true表示清除快取,也就是非持久化訂閱者,這個時候只要引數設為true,一定是非持久化訂閱者。而引數設為false時,表示伺服器保留客戶端的連線記錄,但此時也不一定是持久化訂閱者,這個時候第二個相關的就出場了,就是訂閱時的服務質量,也就是qos。服務質量的概念大致如下:

Quality of Service等級是傳送與接收端的一種關於保證交付資訊的協議。一共有3 QoS等級:

最多一次(0) 最少一次(1)只一次(2

QoS0 —— 最多1

最小的等級就是 0。並且它保證一次資訊盡力交付。一個訊息不會被接收端應答,也不會被髮送者儲存並再傳送。這個也被叫做“即發即棄”。並且在TCP協議下也是會有相同的擔保。

QoS1 ——最少1

當使用QoS等級1 時,它保證資訊將會被至少傳送一次給接受者。但是訊息也可能被髮送兩次甚至更多。傳送者將會儲存傳送的資訊直到傳送者收到一次來自接收者的PUBACK格式的應答。

最高的QoS就是2,它會確保每個訊息都只被接收到的一次,他是最安全也是最慢的服務等級。

當連線完成後,可以進行訂閱操作,此時就需要設定服務質量,在已經傳參setCleanSession為false的情況下,服務質量設為0,仍然是非持久化訂閱者,這是我踩過的坑,當服務質量為1或2時,則完成了持久化訂閱。在ActiveMQ主介面上的Subscribers中可以看到線上的持久化訂閱者、離線的持久化訂閱者以及線上的非持久化訂閱者的情況,裡面還顯示了服務質量的區別,是至少一次(at least once)還是正好一次(exactly once),圖片如下:

使用paho包做持久化訂閱的流程就是這樣,呼叫連線選項的成員方法setCleanSession,設定為false,然後訂閱時引數中的服務質量設定為1或2,即可完成持久化訂閱。