代码之家  ›  专栏  ›  技术社区  ›  Mawillec

在一个消费者隐藏多个用户的情况下,在队列中保留和锁定消息的策略

  •  0
  • Mawillec  · 技术社区  · 6 年前

    我正在尝试实现以下场景,我真的需要并感谢您的帮助。我将ActiveMQ 5.14与camel 2.21结合使用。

    在队列中,每条消息对应于一台机器。这些机器通过一个轮询消费者连接到队列,消费者无法区分。消息应该保留在队列中,直到一台机器确认它已通过单独的请求到达正确的机器。在每次获取一条消息后,该消息应该被锁定一段时间。

    我找不到任何可以解释我的问题的ActiveMQ功能。我的方法是在每次提取后将消息发送到第二个队列,该队列用作锁定机制,并在指定的超时后将其发送回可提取队列。
    如果机器没有确认消息,那么在每次获取后回滚会话可能是更好的方法。

    你对这个问题的可行解决方案有什么建议吗?

    编辑: 更多细节来澄清情况

    应用程序通过两个调用向web公开REST API与客户端通信: 收到 删去 .
    GET从队列中获取下一条消息,DELETE从队列中删除该消息。我需要确保在给定的时间段内只提取一次消息,并且如果客户端不发送删除请求,消息将返回队列。目前,我有一条从rest服务到bean的路由,bean从队列中获取消息,并将其返回到GET请求,然后将其发送回队列。在一个删除请求中,我用给定的id将消息从队列中取出。 我仍然需要找到一种方法来确保在指定的时间段内无法访问最后获取的消息。

    1 回复  |  直到 6 年前
        1
  •  2
  •   burki    6 年前

    我对无法区分机器的部件有点困惑,但我明白以下几点:

    • 您有一个包含消息的队列
    • 你有一个消费者
    • 消费者接收信息并呼叫服务或类似服务
    • 如果通话成功,则可以删除该消息
    • 如果呼叫失败,则必须重新处理消息

    如果这些假设是正确的,您可以构建一个使用队列中的消息的驼峰路由( 交易 )服务和电话。

    • 如果骆驼 路线失败 完成(服务返回错误),错误为 处理后,代理进行回滚,然后 消息被重新传递 (立即)
    • 如果路由多次失败(当达到最大重新交付值时),消息将发送到 死信队列 (经纪人)把它移到一边,但要保存它
    • 如果 路线成功 消息消耗被提交给代理和 删除消息
    • 在这样的设置中,您还可以配置更多消费者来并行处理消息(如果被调用的服务允许)

    这种行为或多或少是默认行为,如果

    • 您的代理配置为持久(避免消息丢失)
    • 您使用已处理的消息(与代理的本地事务就足够了)
    • 骆驼是的 处理错误(当它们被处理时,消息被提交,因为代理没有“看到”任何错误)
    • 你从服务中得到一个错误,或者你至少可以决定是否有问题,然后自己抛出错误。代理必须获取异常,以便完成回滚

    编辑

    根据你的澄清,我理解这与我的假设相反。

    那么,我可能会将这两种请求类型视为“工作流步骤”,因为它们是从客户端触发的。

    收到

    • 使用消息,将其发送给请求者
    • 向消息头添加时间戳
    • 将消息发送到 另一个队列 (我们就叫它吧 delievered )

    删去

    • 将消息从 delievered 队列

    未删除的邮件

    • 使用时间戳头和 message selectors 在一定时间后使用未删除的邮件
    • 将它们移回源队列

    有了第二个队列,你就有了各种优势

    • 正在处理的消息不能再次使用,因此不需要“锁定”
    • 源队列只包含等待的消息 delievered 仅对正在处理的消息进行排队
    • 在将未删除的邮件发送回源队列时,可以提高邮件优先级,以便快速重新使用这些邮件
    • 还可以在将未删除的消息发送回源队列时添加计数器头,以标识多次失败的消息,并以另一种方式处理它们。