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

时间:2018-05-18 15:13:47

标签: java apache-camel activemq

我正在尝试实现以下方案,我真的可以使用并感谢一些帮助。我正在使用带有驼峰2.21的ActiveMQ 5.14。

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

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

您对此问题的可行解决方案有什么建议吗?

修改:更多细节以澄清情况

应用程序通过两次调用将REST API暴露给Web来与客户进行通信: GET DELETE
GET从队列中获取下一条消息,DELETE从队列中删除该消息。我需要确保消息仅在给定时间段内被提取一次,并且如果客户端没有发送DELETE请求,它将返回队列。目前我有一条从其余服务到bean的路由,它从队列中获取消息,将其返回给GET请求,然后将其发送回队列。在DELETE请求中,我使用给定的id从队列中取消消息。 我仍然需要找到一种方法来确保在指定的时间段内无法访问上次获取的消息。

1 个答案:

答案 0 :(得分:2)

我对使用无法区分的机器的部分感到有点困惑,但我理解以下内容:

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

如果这些假设是正确的,您可以构建一个Camel路由,该路由使用来自队列的消息(已处理)并调用该服务。

  • 如果Camel 路由失败完成(服务返回错误)并且错误处理,则代理会执行回滚并重新传递消息< / strong>(立即)
  • 如果路由多次失败(达到最大重新传递值),则会将消息发送到死信队列(由代理)将其移出路径但保存< / LI>
  • 如果路由成功,则将消息提交给代理并删除消息
  • 在这样的设置中,您还可以配置更多的消费者来并行处理消息(如果被叫服务允许的话)

如果

,此行为或多或少是默认行为
  • 您的代理被配置为持久性(避免消息丢失)
  • 您使用已处理的邮件(与代理的本地事务就足够了)
  • Camel 处理错误(处理错误时,邮件已提交,因为代理没有“看到”任何错误)
  • 您从服务中收到错误,或者至少可以确定是否存在问题并自行抛出错误。代理必须获得异常才能完成回滚

修改

根据你的澄清,我明白这是我所假设的另一种方式。

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

获取

  • 使用消息,将其发送给请求者
  • 在邮件标题中添加时间戳
  • 将邮件发送到另一个队列(让我们称之为delievered

删除

  • 将消息从delievered队列
  • 出列

未删除的消息

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

使用第二个队列可以获得各种优势

  • 处理中的邮件无法再次使用,因此无需“锁定”
  • 源队列仅包含等待消息,即处理中的delievered仅队列消息
  • 您可以在将未删除的邮件发送回源队列时提高邮件优先级,以便快速重新使用
  • 您还可以在将未删除的邮件发送回源队列时添加计数器标头,以识别多次失败的邮件并以其他方式处理它们。