消息的簽收是消息被消費的標誌,消息的簽收機制一定程度上來說是爲了避免消息的重複消費問題,因此消息的簽收偏重於消費者,對生產者幾乎是沒有意義,因爲生產者不涉及到簽收。
簽收對消息的影響:
- 對於queue中的消息而言,一旦消息被簽收則這條消息的狀態就會從待消費狀態(Pending Messages )變爲已消費狀態(Messages Dequeued )而從待消費隊列中移除。
- 對於Topic中的消息而言,若採用MessageConsumer的消費模式則消息的簽收機制是沒有任何意義的,因爲MessageConsumer只能消費Topic中從消費者在MQ服務器註冊之後推送到Topic中的消息,至於這之前的消息簽收與否MessageConsumer不關心(因爲接收不到之前的消息),也就是說使用MessageConsumer消費Topic中的消息時是不會存在重複消費的問題的。
- 對於Topic中的消息而言,若採用TopicSubscriber的模式消費消息時簽收機制可以避免重複消費消息的作用就凸顯出來了,此時消息的簽收將會作爲某個訂閱者(以Connection的ClientID作爲標識)已消費過Topic中的某個消息的標誌,也就是說消費者每次上線後都只會消費訂閱的Topic中未被簽收的消息,已簽收的消息則不會被重複消費。
簽收機制有四種:
- Session.AUTO_ACKNOWLEDGE:值爲1,自動簽收,消費一條簽收一條
- Session.CLIENT_ACKNOWLEDGE:值爲2,手動簽收,需顯示調用Message.acknowledge()方法完成簽收
- Session.DUPS_OK_ACKNOWLEDGE:值爲3, "消息可重複"確認,意思是此模式下,可能會出現重複消息,並不是一條消息需要發送多次ACK纔行。它是一種潛在的"AUTO_ACK"確認機制,爲批量確認而生,而且具有“延遲”確認的特點。對於開發者而言,這種模式下的代碼結構和AUTO_ACKNOWLEDGE一樣,不需要像CLIENT_ACKNOWLEDGE那樣調用acknowledge()方法來確認消息。
- Session.SESSION_TRANSACTED:值爲4,以事務的方式簽收
事務對消息簽收的影響:
消息簽收是事務控制的一部分
- 事務的方式,對消息的簽收有影響,只要事務提交就會將所有消息的簽收狀態置爲已簽收,無論之前的簽收狀態是什麼;
- 只要事務不提交則消息的簽收狀態就不起作用(表現上就是隊列中已簽收的消息不會被移出待消費隊列等),會產生重複消費得問題。
- 非事務的方式,不會對消息的簽收有任何影響