谷歌云Pub/Sub重试计数

10
我们正在从一个不稳定的消息队列服务迁移到使用Google Pub Sub在NodeJS中运行。这似乎能够很好地工作,但我们也想包含错误处理。
我们想要限制特定消息的重试次数,在测试环境中为10次,在生产环境中为100次。现在,如果一条消息在测试中失败了10次,而不是让它在我们的队列中继续被处理和失败7天,我们希望将其移动到一个单独的错误队列并发送电子邮件通知我们。
我们当前已经在以前的消息队列中设置了所有这些内容,但我们还没有找到Google的Pub Sub每条消息的重试计数属性。有人知道这个是否存在吗?
我们在Google App Engine中使用任务队列,它们拥有我们需要的一切,但Google的Pub Sub似乎缺少很多。我们确实需要任何解决方案都是在Node中进行的。
3个回答

17
更新于 2020年4月21日:截至今日,Cloud Pub/Sub已发布了死信队列功能。这个功能允许设置消息尝试传送的最大次数,并指定一个主题来发布超过该次数的消息。当启用此功能时,它还会将投递尝试次数作为一个字段公开。例如,在Node.js中通过回调传递给订阅者的消息中显露在deliveryAttempt属性中。

以前的答案

Cloud Pub/Sub没有重试向订阅者传递消息的次数限制。如果您的订阅者在确认期限内从未确认消息,则消息将被重新传送,直到消息在7天后到期。

如果您想要停止接收这些消息,则需要在某个时候确认它们。如果您想保护免遭无法由订阅者处理的“死亡消息”,我建议执行以下操作:

  1. 在数据库中按消息ID追踪消息失败计数。希望故障不会频繁发生,因此这个数据库应该不会太大,只有当实际出现故障时才会对其进行查询。

  2. 当消息失败时,请查询数据库并查看之前发生了多少次失败。如果计数低于您的阈值,则增加计数并不确认消息。

  3. 如果某个消息失败的次数超过了您的阈值,请将该消息发布到单独的“失败消息”主题,发送电子邮件并确认该消息。

  4. 如果需要,在解决导致消息首次失败的问题后,有一种方法可以将来自“失败消息”主题的消息重新发布到您的主要主题中。

现在您已经将消息保存在一个单独的主题中(7天或直到您确认),并且该消息不会被重新传递到您主要主题的订阅者。


谢谢你的回复,Kamal。我认为你的回答可以行,但我们会以稍微不同的方式实施它。由于在数据库中保留消息失败计数似乎是无用信息,特别是如果实际消息消失了,我们将在每个对象上存储入队或发布日期。如果对象停留在主题中一天或更长时间,我们将把消息添加到数据库并从主题中确认/删除它。这使我们能够静音日志,限制重试,并使失败的消息可查看和可用时间超过7天。 - T.Okahara
我们意识到在App Engine中使用任务队列本来是完美的,但是它们不支持Node。再次感谢您的回复! - T.Okahara
Appengine中的任务队列具有REST API(尽管仍带有beta标签)https://cloud.google.com/appengine/docs/python/taskqueue/rest/ - marcadian
@marcadian 是的!我们在其他目前使用Python编写的项目中使用任务队列。NodeJS的任务队列仍在开发中,未来可预见会有一个私人Alpha版本。 - T.Okahara

2

有一种简单的“黑科技”可以实现这一点。

使用死信机制

一旦达到限制,订阅将会将您的消息发布到指定的主题,并且不会再次尝试重发。

enter image description here

在这个新的主题中,您可以使用一个没有重试设置的订阅。这也有利于“减少日志混乱”,因为您可以仅针对失败的消息在新主题中处理这些故障。

-2
在Python中,查看.execute()上的'num_retries'参数:

pubsub_client.projects().topics().publish(topic='projects/xxxx',body=body).execute(num_retries=0)

我不确定Node.JS中是否存在相同的东西,但希望这能为你指明方向。


嗨Aerodyno,这让我非常兴奋。我也在Python文档中看到了它,但当我们查看Python和NodeJS的Github时,它没有被实现或记录。 - T.Okahara
6
num_retries属性将影响发布失败时重试的次数,例如,如果发布者由于某些原因无法到达Cloud Pub/Sub。它不会影响在订阅者无法处理和ack消息的情况下向订阅者传送消息的次数。 - Kamal Aboul-Hosn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接