【发布时间】:2017-09-25 11:49:49
【问题描述】:
我需要确保在消费者失败时重新传递 JMS 消息,但此处接受的类似问题的策略可能不适用于我的情况。
考虑一个 JMS 客户端 - spring + activeMq - 接收消息,这些消息不会丢失或重复。因为消息的处理成本很高,所以客户端对它们进行批处理。剧情如下:
- T1 - 客户端收到消息 A、B、C 和 D
- T2 - 线程在客户端唤醒并决定处理消息 A、B 和 C
- T3 - 客户端收到消息 E 和 F
- T4 - 线程在处理完 A、B 和 C 后返回。如果另一个线程尚未执行此操作,则它可以拾取下一批。
现在设置生产者的方式 - DefaultJmsListenerContainerFactory 和 Session.AUTO_ACKNOWLEDGE - 消息在传递后立即被删除,无论它们是否已被线程与否。如果客户端在 T4 之前停机,则消息 A 到 F 将丢失。
我打算在生产者上使用 Session.CLIENT_ACKNOWLEDGE 并让每个线程在 T4 之后调用 msg.acknowledge(),但根据 documentation,这也会确认 E 和 F,如果客户端在 T4 之后失败,这将丢失。
我也不相信事务处理的会话在这里会有所帮助,因为它会涵盖消息 A 到 F,而线程完成仅保证其中的一部分已被处理。
我的目标是保证在客户失败的情况下,例如虚拟机宕机,所有未由线程成功处理的消息都保留在主题/队列中。然后,当它恢复时,它们可以被客户端拾取。
关于如何实现这一点的任何想法?
S
【问题讨论】:
标签: java spring jms batch-processing spring-jms