【问题标题】:max-delivery-attempts does not work for un-acknowledged messagesmax-delivery-attempts 不适用于未确认的消息
【发布时间】:2020-11-02 22:36:53
【问题描述】:

我注意到 Artemins 的奇怪行为。我不确定这是一个错误还是我不明白什么。 我使用 Artemis Core API。我将autoCommitAcks 设置为false。我注意到如果在MessageHandler 中收到消息,但消息未被确认并且会话被回滚,那么 Artemis 不会认为此消息未送达,Artemis 认为此消息根本没有发送给消费者。参数 ma​​x-delivery-attempts 在这种情况下不起作用。消息被无限次重新传递。方法 org.apache.activemq.artemis.api.core.client.ClientMessage#getDeliveryCount 每次返回 1。消息在 Web 控制台的 Redelivered 列中具有 false 值。如果在会话回滚之前确认消息,则 ma​​x-delivery-attempts 可以正常工作。

消息确认的目的究竟是什么?确认意味着仅接收到消息,还是确认意味着成功接收和处理消息?也许我可以同时使用确认,这仅取决于我的要求?

通过消息确认我的意思是调用org.apache.activemq.artemis.api.core.client.ClientMessage#acknowledge 方法。

【问题讨论】:

    标签: activemq-artemis


    【解决方案1】:

    您看到的行为是预期的。

    核心客户端实际上是从一个 local 缓冲区中消费消息,该缓冲区以异步方式填充来自代理的消息。此本地缓冲区中的消息数据量由客户端 URL 上设置的 consumerWindowSize 控制。代理可能会向位于这些本地缓冲区中的各种客户端发送数千条消息,而消费者从未真正以任何身份看到过这些消息。这些消息被视为正在传递,其他客户端不可用,但它们未被视为已传递。只有当消息被确认时,它才会被认为是传递给客户端。

    如果客户端自动提交确认,则确认消息将快速将其从其各自的队列中删除。一旦消息从队列中删除,它就不能再被重新传递,因为它不再存在于代理上。简而言之,如果您自动提交确认,您将无法获得可配置的重新传递语义。

    然而,如果客户端不自动提交确认并且消费者关闭(出于任何原因)没有提交确认或在其ClientSession上调用rollback(),那么确认的消息将是根据配置的重新交付语义(包括max-delivery-attempts)重新交付。

    【讨论】:

    • 我不知道在使用自动提交确认时如何使用配置的重新传递语义。如果消息被确认,则无论会话是提交还是回滚,都认为消息已传递。如果消息未被确认并且会话被回滚,则消息将被无限次重新传递。因此,仅在关闭自动提交确认时才使用重新传递语义。
    • 我更新了我的答案以使事情更清楚。希望有帮助。如果我的回答解决了您的问题,请将其标记为正确,以帮助将来有同样问题的其他人。谢谢!
    猜你喜欢
    • 2021-07-15
    • 2013-05-24
    • 2019-09-21
    • 2021-10-30
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 2013-12-30
    • 2015-11-24
    相关资源
    最近更新 更多