从 ActiveMQ Artemis 队列重新传递 JMS 消息

问题描述 投票:0回答:2

我目前正在实现一个消费者,它监听 ActiveMQ Artemis Broker 发送的事件。

我发现这篇文章说:

1 & 2 和 3 & 4 之间的主要区别是后者允许在处理过程中发生错误时回滚并重新传递消息

所以我认为 1 和 2(客户确认)的重新交付是不可能 可能的。

这里在 Apache 的文档中是这么说的

消息可能无法成功传递(例如,如果用于使用消息的事务会话被回滚)

我认为

CLIENT_ACKNOWLEDGE
不是交易,所以这无效,对吗?

所以,如果我设置

<redelivery-delay>300000</redelivery-delay>
,5 分钟后会有消息重新发送吗?

Spring 文档这里 说:

“sessionAcknowledgeMode”设置为“CLIENT_ACKNOWLEDGE”:监听器执行成功后自动消息确认; 尽最大努力重新交付,以防引发用户异常以及其他侦听器执行中断(例如 JVM 死亡)。

这有点令人困惑。我还发现了 ActiveMQ Artemis 的配置,所以我有这些问题:

  1. 可以通过
    CLIENT_ACKNOWLEDGE
  2. 重新投递吗
  3. 如果是,使用
    @Transactional
    重新投递和省略
    Message.acknowledge()
    调用有什么区别?我应该更喜欢哪一个?
  4. 如果不是,Spring 文档的实际含义是什么?
spring-jms activemq-artemis
2个回答
0
投票

对于要重新传递的消息,Artemis 消息代理必须知道该消息需要重新传递。

CLIENT_ACKNOWLEDGE
模式下,没有超时,但 JMS 会话可能会因各种原因失败。例如,启动您的客户端,使用但不确认消息。然后杀死你的客户端(终止java进程)。这些消息将可用于传递/重新传递。

在事务会话的情况下,如果事务上下文失败(超时等),则消息将再次可用于传递。与上述相同的条件也适用于交易案例中失败的会话。


0
投票

您从 ActiveMQ Classic 引用的此文档具有误导性:

客户端消费消息有四种主要方法。他们是:

  1. 自动确认
  2. 通过
    Message.acknowledge()
  3. 明确确认
  4. JMS 事务
  5. XA

...

1 & 2 和 3 & 4 之间的主要区别是后者允许在处理过程中发生错误时回滚并重新传递消息。不存在 JMS“取消确认”。因此,在大多数用例中,JMS 事务应该优先于消息确认。

事实是,

Message.acknowledge()
与使用 JMS 事务是正交。换句话说,您可以在有交易的情况下使用
Message.acknowledge()
,也可以在没有交易的情况下使用

如果将

Message.acknowledge()

 与事务一起使用,则 JMS 上的 
rollback()
 
Session
 可能会导致消息重新传送,具体取决于代理的配置方式。我不想说回滚 
Session
 总是会导致重新传递,因为在某些情况下,代理可能会将消息发送到死信队列或可能将其完全删除(例如,如果消息已经被重新传递“太多”) “次)。

如果您在没有事务的情况下使用

Message.acknowledge()

,则消息将从队列中删除,以后无法恢复。当然,这是假设确认实际上通过网络到达了代理。在发送确认之前,可能会出现网络错误或 JVM 可能会死亡(无论出于何种原因),在这种情况下,即使您的应用程序调用了 
Message.acknowledge()
,消息也不会被确认。我相信这本质上就是 Spring 文档所指的内容。如果 
CLIENT_ACKNOWLEDGE 在未确认消息的情况下关闭,则可以通过 Session
 重新投递 
无论您使用事务处理会话还是 

CLIENT_ACKNOWLEDGE

,如果您想确认消息,您都必须至少调用

Message.acknowledge()
您是否喜欢使用事务处理会话完全取决于您的用例。

© www.soinside.com 2019 - 2024. All rights reserved.