如何使用 Node.js 控制 Cloud PubSub 中的确认
Posted
技术标签:
【中文标题】如何使用 Node.js 控制 Cloud PubSub 中的确认【英文标题】:How can I control acknowledgement in Cloud PubSub using Node.js 【发布时间】:2018-03-30 00:29:00 【问题描述】:基本上我已经创建了一个云函数(编写了一个 Node.js 代码),它将触发云 pubsub 主题的消息并将该数据加载到 Bigquery 表中。
主题中的消息在通过云功能阅读后被删除。我知道订阅者在内部发送确认和结果,消息被从主题中删除。
我想控制发送给发布者的确认。怎么实现的,没找到这方面的文档。
【问题讨论】:
您是手动执行此操作还是使用 Googels 客户端库之一?客户端库旨在自行返回 ack 我认为您将不得不看看是否有办法将其关闭。 【参考方案1】:Google Cloud Functions 不允许您控制对 Cloud Pub/Sub 消息的确认。完成该功能后,将确认订阅的消息。如果您想对确认进行更细粒度的控制,则需要直接使用 Google Cloud Pub/Sub。有一个Node.js client library。
只是一些关于确认的澄清说明:确认单个订阅的消息并不意味着删除该主题的消息,仅删除该订阅的消息。其他独立订阅仍将收到该消息并必须确认它。这也与发送给发布者的确认无关。发布 Google Cloud Pub/Sub 消息后,一旦 Google Cloud Pub/Sub 保存消息并保证将其传递给订阅者,就会确认发布调用(即,向发布者发送响应)。这是异步消息传递系统的主要优点之一:从发布者接收消息(并确认发布)与通过订阅(订阅者单独确认)传递消息无关。
【讨论】:
感谢卡马尔的解释。关于您关于确认的注释:如果我有 3 个订阅该主题并且其中一个订阅者没有发送确认(根据您的评论,消息不会从主题中删除)那么其他两个订阅者可以再次从该主题中读取相同的消息吗? 如果单个订阅未确认消息,则只有该订阅应再次获取消息(需要注意的是,Pub/Sub 通常至少传递一次)。消息的确认是每个订阅。 @kamal 我们发现node.js pubsub client 不能很好地与云功能配合使用,因为它会在后台发送确认 (taboo for cloud functions) 并尝试重用连接。见my SO question。【参考方案2】:我发现可靠控制哪些消息在云函数中得到确认和不确认的唯一方法是使用REST Service APIs。
这是因为node.js pubsub client 服务在后台确认和管理连接。这是clearly forbidden in a cloud function。
但是,REST API 相当容易使用,并且可以精细控制哪些消息得到确认。
【讨论】:
【参考方案3】:如果我理解正确;您创建了一个发布/订阅主题并将云功能放置在与该主题相同的项目中。使用指定主题的 google.pubsub.topic.publish 触发器部署云函数。
由于使用队列/主题,生产者和消费者彼此独立运行。这实现了一个松散耦合的架构,它有自己的advantages and disadvantages。
如果发布者向主题发布消息,它会确认消息已成功发送到主题。否则,您的代码将给出异常(连接被拒绝、禁止等)。对于Node.js 和其他语言,有 pub/sub 客户端 sdk,您可以使用它们相当轻松地发布消息。
当消息在主题上时,它会发送给订阅者,订阅者可以是推送订阅,也可以是拉取订阅。在这一点上,确认变得越来越重要。与其他队列/主题一样,Google pub/sub 的设计都是有保证的交付。这意味着如果无法传递消息,它将在一段时间(可配置)后重试,直到超过总生命周期(默认为 7 天) 当使用请求订阅并想让主题知道您已成功收到消息时,您需要在 Node.js 中使用类似的内容:
message.ack();
当使用 API 或 HTTP 云函数的推送订阅时,您需要返回自定义 http 代码。 Pub/sub 需要一个成功的状态码(例如 200 或 204):
res.status(204);
res.send('OK');
【讨论】:
以上是关于如何使用 Node.js 控制 Cloud PubSub 中的确认的主要内容,如果未能解决你的问题,请参考以下文章
Google Cloud Vision - 如何使用 Node.js 发送请求属性
如何使用 Google Cloud Compute Engine 为 Node.JS 应用程序配置端口转发
如何访问 Cloud Function node.js10 中的 Secret Manager?
如何使用 Node.js 将 base64 编码图像(字符串)直接上传到 Google Cloud Storage 存储桶?