1

我正在尝试使用拉取队列来创建图像处理任务队列,这些任务可能需要比 10 分钟的 acktimeout 限制更长的时间。我正在使用 node.js api,我想知道如何让工作人员从拉取队列中抓取一条消息,将其标记为正在进行中,这样其他工作人员就不会尝试抓取它,完成它的工作并在之后确认消息处理完成。此处理可能需要每个工人一个小时。如果发生异常,我想删除“进行中”状态并允许其他工作人员获取此消息并尝试处理它。

我希望 pubsub 中有一些东西可以让我这样做。我的替代方法是,在处理之前,将带有消息 id、ack id、status=pending、timestamp=now() 的实体(inProgressMessage)存储到数据存储中,让工作人员在收到消息后立即返回 ackid(这将允许其他工作人员尝试其他消息),然后工作人员可以处理冗长的任务。如果成功,将实体状态标记为完成,如果以非永久方式失败,将任务重新排队到 pubsub,如果以不允许重新排队的永久方式失败,我可以让 cron 检查数据存储中是否存在比几个旧的待处理任务小时并让它们被删除或重新排队。

我的替代方案感觉就像我正在重新实现 pub sub 应该帮助的很多内容。

如果您能想到更好的方法,请告诉我。

4

2 回答 2

5

要花费比确认截止日期更长的时间来处理消息,您需要使用modifyAckDeadline。您可以根据需要多次延长截止日期,每次通话最多 10 分钟。您的工作流程如下:

  1. 拉消息。
  2. 开始处理消息。
  3. 当您没有完成消息时,如果您接近 10 分钟的确认截止日期,请调用 modifyAckDeadline 以延长截止日期。
  4. 处理完消息后,确认它。

请注意,调用 modifyAckDeadline 并不能保证消息不会被传递到另一个任务。在某些情况下,例如服务器重新启动,消息可能最终会传递给您的另一个订阅者。但是,在大多数正常情况下,只要在当前 ack 截止日期之前调用 modifyAckDeadline,就可以在必要时阻止消息的重新传递。

于 2016-05-11T12:23:36.223 回答
0

创建主题时(仅),您可以将确认时间配置为最长10 分钟https://cloud.google.com/pubsub/subscriber)。一旦从队列中拉出一条消息,(同一个订阅者的)其他工作人员将无法处理它,除非到达 ack ttl,然后消息会自动返回到队列中。

由于您需要更长的时间,您将不得不自己实现某些东西,或者寻求另一个排队解决方案。我认为您建议的设计实现起来相当简单,并不是真正重新实现 pubsub 所做的事情。

于 2016-05-11T11:49:41.290 回答