前面一章中介紹了activemq的初步實現:基於ActiveMQ的Topic的數據同步——初步實現
下面來解決持久化訂閱的問題:
(1)使用queue,即隊列時,每個消息只有一個消費者,所以,持久化很簡單,只要保存到數據庫即可
。然后,隨便一個消費者取走處理即可。某個消費者關掉一陣子,也無所謂。
(2)使用topic,即訂閱時,每個消息可以有多個消費者,就麻煩一些。
首先,假設消費者都是普通的消費者,
------------------------
<1>activemq啟動后,發布消息1,可惜,現在沒有消費者啟動着,也就是沒有消費者進行了訂閱。那么
,這個消息就被拋棄了。
<2>消費者1啟動了,連接了activemq,進行了訂閱,在等待消息~~
activemq發布消息2,OK,消費者1收到,並進行處理。消息拋棄。
<3>消費者2也啟動了,連接了activemq,進行了訂閱,在等待消息~~
activemq發布消息3,OK,消費者1,消費者2都收到,並進行處理。消息拋棄。
<4>消費者1關掉了。
activemq發布消息4,OK,消費者2收到,並進行處理。消息拋棄。
<5>消費者1又啟動了。
activemq發布消息5,OK,消費者1,消費者2都收到,並進行處理。消息拋棄。
-----------------------------
總結一下:
activemq只是向當前啟動的消費者發送消息。
關掉的消費者,會錯過很多消息,並無法再次接收這些消息。
如果發送的消息是重要的用戶同步數據,錯過了,用戶數據就不同步了。
那么,如何讓消費者重新啟動時,接收到錯過的消息呢?
答案是持久訂閱。
(3)普通的訂閱,不區分消費者,場地里有幾個人頭,就扔幾個饅頭。
持久訂閱,就要記錄消費者的名字了。
張三說,我是張三,有饅頭給我留着,我回來拿。
李四說,我是李四,有饅頭給我留着,我回來拿。
activemq就記下張三,李四兩個名字。
那么,分饅頭時,還是一個人頭給一個饅頭。
分完了,一看張三沒說話,說明他不在,給他留一個。
李四說話了,那就不用留了。
張三回來了,找activemq,一看,這不張三吧,快把他的饅頭拿來。
可能是一個饅頭,也可能是100個饅頭,就看張三離開這陣子,分了多少次饅頭了。
原理講完,下面是配置實現:
修改jms-receiver.xml:原來的同樣位置改成這樣就可以了。在發送者中不用設置clinetIDPrefix屬性也可以。
<!--異步調用消息 --> <bean id="receive" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="jmsReceiverFactory"></property> <property name="destination" ref="destination"></property> <property name="messageListener" ref="messageListener"></property> <property name="subscriptionDurable" value="true"></property> <property name="clientId" value="www_01"></property> <property name="durableSubscriptionName" value="www"></property> </bean>
以下是mq中的截圖: