當消費者失敗時,我需要確保重新傳遞JMS消息,但這裏類似問題上接受的策略可能不適用於我的情況。如何在客戶端崩潰時確保JMS消息重新傳遞
考慮一個JMS客戶端 - spring + activeMq--接收不會丟失或重複的消息。由於消息的處理非常昂貴,客戶端會批量處理它們。場景播放如下:
- T1 - 客戶端接收消息A,B,C和d
- T2 - 線程在客戶端上被喚醒並決定處理消息A,B和C
- T3 - 客戶端收到消息E和F
- T4 - 線程返回已處理A,B和C的數據。如果另一個線程尚未完成,它可以接收下一批。
生產者建立現在的方式 - 消息,儘快爲他們交付刪除,是否已經由一個線程拿起與否 -和Session.AUTO_ACKNOWLEDGEDefaultJmsListenerContainerFactory。如果客戶在T4之前停機,則消息A到F將丟失。
我正打算使用Session.CLIENT_ACKNOWLEDGE在生產者和獲得每個線程T4之後調用msg.acknowledge(),但根據documentation,這也將確認E和F,這將是如果客戶在T4之後失敗,則丟失。
我不確定交易會話是否會對此有所幫助,因爲它將涵蓋消息A到F,而線程完成只保證已處理該消息的子集。
我的目標是保證在發生客戶端故障時(例如,虛擬機停機,所有尚未被線程成功處理的消息都保留在主題/隊列中。當客戶回來時,他們可以被客戶接收。
關於如何實現這一點的任何想法?
小號
是的,auto_ack在onMessage()完成後完成。目前,此方法僅將消息添加到集合(以簡化)並返回。當滿足某些條件(時間,集合的大小...)時,線程決定是時候處理集合中的部分消息。這意味着在auto_ack中,msg ack和實際處理之間會有一段時間。也許我所追求的是不可行的,正如你所說的,我只需要配置集合的大小以至多保留我可以承受的最小丟失數量。 –
在這種情況下,實際上您可以使用像mapdb或smth這樣的持久數據結構。從發送郵件到某個內部渠道的那一刻起,實際上您有責任在此郵件的進一步訪問後留心。試圖通過經紀人完成這項工作將導致複雜的邏輯沒有任何需要。但對我來說,即使mapdb看起來像一個開銷,我懷疑你的情況是一個好的架構。從我的角度來看,最好的選擇就是建議您可以丟失或獲取一些較低信息量的重複項並設置合適的窗口大小 –