架构:
我们有一个架构,它使用了两个公共主题/订阅对:
T1是由一个周期性的任务触发的(例如,每5分钟一次)。订阅S1是云功能的触发器。T2充当由我们的服务发布的后台作业的队列。订阅S2由云函数在每次执行时读取,以服务排队的后台作业。这允许我们控制后台作业被服务的频率,而不依赖于它们被添加到队列中的时间。
云函数(由S1触发)通过拉扯从S2读取消息。它决定哪些后台作业已经准备好,并在成功地为作业提供服务后,ACK提供了相关的消息。未准备好或失败的作业以后将不会服务于ACK‘。
问题:
我们在使用google的官方node.js耻骨客户端时遇到了问题:
ack()。S2中的消息排队。我们认为这是谷歌的node.js公开客户端的一个问题。云函数文档清楚地声明了不开始背景活动。但是,查看node.js发布子客户端源,它显然使用超时在后台为确认提供服务。
是谷歌的node.js发布客户端不兼容谷歌云功能吗?谷歌 建议只在客户端库不存在或不满足其他需要时才访问服务API。在云函数中运行客户端是否“其他需求”,要求我们使用服务API的编写自己的客户端?
解决办法尝试:
作为一种“解决办法”,我们尝试延迟执行cloudfunction的结束,以允许node.js pubsub客户端中的任何“后台”进程完成,但这并没有始终消除我们的问题。看起来,pubsub客户端对云功能不友好,无法从执行云功能之间的停顿中恢复过来。
更新2018年2月22日
我编写了我们博客上的一篇文章,详细描述了为什么我们以这种方式使用PubSub,以及我们是如何围绕node.js pubsub与云功能不兼容这一事实开展工作的。
发布于 2018-02-22 13:30:18
发布于 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应用程序只用于这个(设置一个最大的实例)将在总自由极限内,所以成本不会明显增加。
发布于 2018-07-22 17:30:11
我遇到了同样的问题,我想更好地控制.ack()。查看谷歌的nodejs库,可以选择重构ack()以返回承诺,以便该函数可以等待ack()完成。
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);
};https://stackoverflow.com/questions/48623991
复制相似问题