之前寫(xiě)的spring activemq整合的demo ,今天繼續(xù)完善一下這個(gè)demo,讓功能更強(qiáng)大。
Spring ActiveMQ 整合(一): 一個(gè)簡(jiǎn)單的demo,測(cè)試消息的發(fā)送與接收
繼上篇文章之后,我消息發(fā)送失敗后,可以重新發(fā)送了。但是至于別人有沒(méi)有收到,這就不得而而而知了。
這時(shí)候就要用到ACK確認(rèn)機(jī)制了。
1.ACK機(jī)制:
ACK (Acknowledgement),即確認(rèn)字符,在數(shù)據(jù)通信中,接收站發(fā)給發(fā)送站的一種傳輸類(lèi)控制字符。表示發(fā)來(lái)的數(shù)據(jù)已確認(rèn)接收無(wú)誤。
JMS API中約定了Client端可以使用四種ACK_MODE,在javax.jms.Session接口中:
- AUTO_ACKNOWLEDGE = 1 自動(dòng)確認(rèn)
- CLIENT_ACKNOWLEDGE = 2 客戶(hù)端手動(dòng)確認(rèn)
- DUPS_OK_ACKNOWLEDGE = 3 自動(dòng)批量確認(rèn)
- SESSION_TRANSACTED = 0 事務(wù)提交并確認(rèn)
此外AcitveMQ補(bǔ)充了一個(gè)自定義的ACK_MODE: INDIVIDUAL_ACKNOWLEDGE = 4 單條消息確認(rèn)
我們?cè)陂_(kāi)發(fā)JMS應(yīng)用程序的時(shí)候,會(huì)經(jīng)常使用到上述ACK_MODE,其中"INDIVIDUAL_ACKNOWLEDGE "只有ActiveMQ支持,當(dāng)然開(kāi)發(fā)者也可以使用它. ACK_MODE描述了Consumer與broker確認(rèn)消息的方式(時(shí)機(jī)),比如當(dāng)消息被Consumer接收之后,Consumer將在何時(shí)確認(rèn)消息。對(duì)于broker而言,只有接收到ACK指令,才會(huì)認(rèn)為消息被正確的接收或者處理成功了,通過(guò)ACK,可以在consumer與Broker之間建立一種簡(jiǎn)單的“擔(dān)?!睓C(jī)制.
Client端指定了ACK_MODE,但是在Client與broker在交換ACK指令的時(shí)候,還需要告知ACK_TYPE,ACK_TYPE表示此確認(rèn)指令的類(lèi)型,不同的ACK_TYPE將傳遞著消息的狀態(tài),broker可以根據(jù)不同的ACK_TYPE對(duì)消息進(jìn)行不同的操作。
比如Consumer消費(fèi)消息時(shí)出現(xiàn)異常,就需要向broker發(fā)送ACK指令,ACK_TYPE為"REDELIVERED_ACK_TYPE",那么broker就會(huì)重新發(fā)送此消息。在JMS API中并沒(méi)有定義ACT_TYPE,因?yàn)樗ǔJ且环N內(nèi)部機(jī)制,并不會(huì)面向開(kāi)發(fā)者。ActiveMQ中定義了如下幾種ACK_TYPE(參看MessageAck類(lèi)):
- DELIVERED_ACK_TYPE = 0 消息"已接收",但尚未處理結(jié)束
- STANDARD_ACK_TYPE = 2 "標(biāo)準(zhǔn)"類(lèi)型,通常表示為消息"處理成功",broker端可以刪除消息了
- POSION_ACK_TYPE = 1 消息"錯(cuò)誤",通常表示"拋棄"此消息,比如消息重發(fā)多次后,都無(wú)法正確處理時(shí),消息將會(huì)被刪除或者DLQ(死信隊(duì)列)
- REDELIVERED_ACK_TYPE = 3 消息需"重發(fā)",比如consumer處理消息時(shí)拋出了異常,broker稍后會(huì)重新發(fā)送此消息
- INDIVIDUAL_ACK_TYPE = 4 表示只確認(rèn)"單條消息",無(wú)論在任何ACK_MODE下
- UNMATCHED_ACK_TYPE = 5 BROKER間轉(zhuǎn)發(fā)消息時(shí),接收端"拒絕"消息
到目前為止,我們已經(jīng)清楚了大概的原理: Client端在不同的ACK_MODE時(shí),將意味著在不同的時(shí)機(jī)發(fā)送ACK指令,每個(gè)ACK Command中會(huì)包含ACK_TYPE,那么broker端就可以根據(jù)ACK_TYPE來(lái)決定此消息的后續(xù)操作.
上面這一段呢就是:ACK_MODE與ACK_TYPE. 想要更多的了解,有興趣的可以自行去看看,這里由于本文的重點(diǎn)是怎么實(shí)現(xiàn),具體原理,可以自行了解一下。
2.實(shí)現(xiàn)消息確認(rèn):
1.首先在配置文件中配置你的應(yīng)答方式是什么。我這里配置的是點(diǎn)對(duì)點(diǎn)的消息確認(rèn)方式。
- <!-- 消息監(jiān)聽(tīng)容器 消息接收監(jiān)聽(tīng)器用于異步接收消息 -->
- <bean id="jmsContainerOne" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
- <property name="connectionFactory" ref="connectionFactory" />
- <property name="destination" ref="destinationOne" />
- <property name="messageListener" ref="consumerMessageListenerOfOne" />
- <pre name="code" class="html"> <!-- 應(yīng)答模式是 INDIVIDUAL_ACKNOWLEDGE http://blog.csdn.net/yueding_h/article/details/54944254 --></pre> <property name="sessionAcknowledgeMode" value="4"></property> </bean>
- <pre></pre>
- <br>
- <h4><a name="t4"></a>2.在接收的代碼中,手動(dòng)確認(rèn) </h4>
- :給消息發(fā)送者一個(gè)回應(yīng)“我收到你的消息了,你可以出隊(duì)了”,activemq在沒(méi)有配置應(yīng)答方式的時(shí)候,他是默認(rèn)確認(rèn)的。但是需求的各不同,就需要有不同的配置
- //只要被確認(rèn)后 就會(huì)出隊(duì),接受失敗沒(méi)有確認(rèn)成功,會(huì)在原隊(duì)列里面
- an style="font-family:Microsoft YaHei;"> </span>textMsg.acknowledge();
- 以上就完成了activemq的消息確認(rèn)。