【问题标题】:ActiveMq, what happens if Client terminates before AckActiveMq,如果客户端在 Ack 之前终止会发生什么
【发布时间】:2012-06-30 11:11:38
【问题描述】:

我有一个持久队列,非事务性,客户端确认,消费者使用 jms.prefetchPolicy.queuePrefetch=1&wireFormat.maxInactivityDuration=50000 读取

一旦消费者处理了一条消息,它就确认该消息。

如果消费者读取了消息,在它可以发送一个 ack 之前,进程突然终止,那么 ActiveMq 中会发生什么? (什么 ActiveMq 参数在这里起作用?)

这与消费者需要 10 分钟来处理消息有什么不同(因此消费者任务是活跃的并且正在工作),ActiveMq 如何知道消息仍在处理中? (它是否监控 TCP/IP 连接,如果连接断开,它会假定消息不会被 Ack'ed?)

我如何确定一条消息是否是“毒丸”,即它会使消费者崩溃? (如果消费者任务没有终止,重新传递计数似乎是有效的;消息中是否有一个内部计数器显示“它已被读取 n 次而没有成功确认?”)

作为一个实验,我发送了 6 条消息,其中一条是“毒丸”(在消费者可以发送 ack 之前杀死消费者),同时运行 2 个消费者(并自动重新启动消费者以使计数达到 2每当消费者死亡时)。查看队列(使用 jconsole,我使用 broker.setUseJmx(true) 启用 jmx),已传递 4 条消息,2 条正在传输中。为什么会有 2 个在飞行中而不是只有一个?

一段时间以来,我一直在阅读 ActiveMq 和 JMS 规范,但没有明确/确凿的答案,因此任何有关哪些参数起作用以及是否存在任何已知错误的见解都会非常有用。

【问题讨论】:

    标签: jms activemq


    【解决方案1】:

    这纯粹是基于我对 JMS 的理解——可能并不完全正确:

    如果消费者读取了消息,在它可以发送 ack 之前,进程突然终止,ActiveMq 中会发生什么

    我的理解是,由于这发生在与 JMS 提供者的会话上下文中,JMS 提供者知道会话是否不再处于活动状态或失败,并且任何未确认为会话一部分的消息将在会话时重新传递重新建立。

    我如何确定一条消息是否是“毒丸”,即是否让消费者崩溃?

    正如您所提到的,JMS 提供程序会跟踪可能在消息头中重新传递消息的次数

    4 条消息已发送,2 条正在发送中

    不确定这一点

    【讨论】:

    • 这有帮助,谢谢。我认为 ActiveMq 会意识到 TCP/IP 连接是否中断(甚至可能在消费者端有一个退出钩子以更快地完成它)。这些消息(其消费者突然退出)实际上正在重新传递。
    • 毒丸:我验证了当我的消费者崩溃时,JMS 确实保留了重新传递消息的 # 次,因此我可以使用它来确定它是否是“毒丸”消息(如果 # 重试超过 x,我记录并确认它)。代码:org.apache.activemq.command.ActiveMQMessage amqMessage = (org.apache.activemq.command.ActiveMQMessage) jmsMessage; int redeliveryCounter = amqMessage.getRedeliveryCounter();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    • 2021-01-05
    • 1970-01-01
    • 2022-01-05
    • 2020-12-27
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多