JMS 消息“什么时候算被确认”决定了消息会不会丢、会不会重复。这篇用进程内的 Artemis broker,把四种确认方式、监听器异常、事务回滚和死信队列的行为逐个跑出来。
AUTO_ACKNOWLEDGE:消费者 A 取到 m1(JMSRedelivered=false,JMSXDeliveryCount=1),还没来得及处理就崩溃(直接关闭连接)
之后消费者 B 能取到:[m2(JMSRedelivered=false,JMSXDeliveryCount=1), m3(JMSRedelivered=false,JMSXDeliveryCount=1)]
CLIENT_ACKNOWLEDGE:消费者 A 取到 m1(JMSRedelivered=false,JMSXDeliveryCount=1),还没来得及处理就崩溃(直接关闭连接)
之后消费者 B 能取到:[m1(JMSRedelivered=true,JMSXDeliveryCount=2), m2(JMSRedelivered=false,JMSXDeliveryCount=1), m3(JMSRedelivered=false,JMSXDeliveryCount=1)] 消费者 A 收到 m1、m2、m3,只对第 2 条 m2 调用 acknowledge()
之后消费者 B 能取到:[m4(JMSRedelivered=false,JMSXDeliveryCount=1), m5(JMSRedelivered=false,JMSXDeliveryCount=1)](m1、m3 没有被确认过,也不会再来)监听器前两次抛出 RuntimeException,第三次成功:收到的投递依次是 [m1(JMSRedelivered=false,JMSXDeliveryCount=1), m1(JMSRedelivered=true,JMSXDeliveryCount=2), m1(JMSRedelivered=true,JMSXDeliveryCount=3)]
第 1 次 receive:m1(JMSRedelivered=false,JMSXDeliveryCount=1) rollback 之后立刻 receive:m1(JMSRedelivered=true,JMSXDeliveryCount=2) 再 rollback 之后 receive:m1(JMSRedelivered=true,JMSXDeliveryCount=3) commit 之后队列里剩余:[] 生产者事务里发送了 2 条但还没 commit:另一个消费者 500 ms 内能取到 [] commit 之后:[tx1(JMSRedelivered=false,JMSXDeliveryCount=1), tx2(JMSRedelivered=false,JMSXDeliveryCount=1)] 再发送 tx3 并 rollback:队列里 []
每次 receive 后都 rollback:共被投递 3 次:[m1(JMSRedelivered=false,JMSXDeliveryCount=1), m1(JMSRedelivered=true,JMSXDeliveryCount=2), m1(JMSRedelivered=true,JMSXDeliveryCount=3)];之后 receive 返回 null 原队列 q5 里剩余:[] 死信队列 DLQ 里的消息:[m1(JMSRedelivered=false,JMSXDeliveryCount=1),_AMQ_ORIG_QUEUE=q5]