当消费者失败时,我需要确保重新传递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看起来像一个开销,我怀疑你的情况是一个好的架构。从我的角度来看,最好的选择就是建议您可以丢失或获取一些较低信息量的重复项并设置合适的窗口大小 –