首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >node.js客户端与google云功能不兼容

node.js客户端与google云功能不兼容
EN

Stack Overflow用户
提问于 2018-02-05 13:44:51
回答 3查看 1.1K关注 0票数 5

架构:

我们有一个架构,它使用了两个公共主题/订阅对:

  • 主题T1是由一个周期性的任务触发的(例如,每5分钟一次)。订阅S1是云功能的触发器。
  • Topic T2充当由我们的服务发布的后台作业的队列。订阅S2由云函数在每次执行时读取,以服务排队的后台作业。

这允许我们控制后台作业被服务的频率,而不依赖于它们被添加到队列中的时间。

云函数(由S1触发)通过拉扯S2读取消息。它决定哪些后台作业已经准备好,并在成功地为作业提供服务后,ACK提供了相关的消息。未准备好或失败的作业以后将不会服务于ACK‘。

问题:

我们在使用google的官方node.js耻骨客户端时遇到了问题:

  1. 有时ACK‘’ed消息会再次出现(似乎无限地)。我们在ACK截止日期之前验证了消息是被加到的,并且通过调查日志来确定我们是在调用ack()
  2. 有时在第一次执行之后(在重新部署函数之后),后续的执行永远不会收到新的消息。我们可以通过在堆栈驱动程序中验证未确认的消息计数,或者通过重新部署函数和查看消息得到服务来验证订阅S2中的消息排队。

我们认为这是谷歌的node.js公开客户端的一个问题。云函数文档清楚地声明了不开始背景活动。但是,查看node.js发布子客户端源,它显然使用超时在后台为确认提供服务。

是谷歌的node.js发布客户端不兼容谷歌云功能吗?谷歌 建议只在客户端库不存在或不满足其他需要时才访问服务API。在云函数中运行客户端是否“其他需求”,要求我们使用服务API的编写自己的客户端?

解决办法尝试:

作为一种“解决办法”,我们尝试延迟执行cloudfunction的结束,以允许node.js pubsub客户端中的任何“后台”进程完成,但这并没有始终消除我们的问题。看起来,pubsub客户端对云功能不友好,无法从执行云功能之间的停顿中恢复过来。

更新2018年2月22日

我编写了我们博客上的一篇文章,详细描述了为什么我们以这种方式使用PubSub,以及我们是如何围绕node.js pubsub与云功能不兼容这一事实开展工作的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-02-22 13:30:18

来自node.js pubsub客户端已确认的开发人员认为,使用客户机从云函数中提取消息并不是受支持的用例。

另一种选择是使用服务API。但是,当尝试从订阅中提取所有消息时,REST具有他们自己的警告

票数 1
EN

Stack Overflow用户

发布于 2018-02-09 16:47:08

你是怎么触发你的功能的?

根据文档,如果您的函数正在使用pubsub消息,那么您应该使用pubsub触发器。当使用pubsub触发器时,不需要库。只需在函数结束时调用callback(),就可以正确地确认pubsub消息。

对于您打算做的事情,我不认为您当前的架构是正确的选择。

我将使用cron任务将您的第一步移到Google,并将此任务简单地从T2移动到T1,让函数拥有触发器S2并处理消息。

因此,您的作业将在T2上发布,您将有一个带有cron任务触发的拉订阅S2的GAE应用程序,这个应用程序会将消息重新发布到T1。然后,您的函数将由主题S1的订阅T1触发,并在消息中运行作业,避免导入pubsub库的额外处理,并按预期使用该产品。

此外,我不知道您最初是如何将您的作业发布到主题中的,但是对于限制速率的任务,任务队列是一个很好的GAE (和阿尔法产品不可知论者)选项。

一个GAE应用程序只用于这个(设置一个最大的实例)将在总自由极限内,所以成本不会明显增加。

票数 1
EN

Stack Overflow用户

发布于 2018-07-22 17:30:11

我遇到了同样的问题,我想更好地控制.ack()。查看谷歌的nodejs库,可以选择重构ack()以返回承诺,以便该函数可以等待ack()完成。

代码语言:javascript
复制
Subscriber.prototype.ack_ = function(message) {
  var breakLease = this.breakLease_.bind(this, message);

  this.histogram.add(Date.now() - message.received);

  if (this.writeToStreams_ && this.isConnected_()) {
    this.acknowledge_(message.ackId, message.connectionId).then(breakLease);
    return;
  }

  this.inventory_.ack.push(message.ackId);
  this.setFlushTimeout_().then(breakLease);
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48623991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档