天天看點

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),圖檔如下:

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

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