Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GCP云功能未正确拾取/确认PubSub消息_Python_Google Cloud Platform_Google Cloud Functions_Google Cloud Pubsub - Fatal编程技术网

Python GCP云功能未正确拾取/确认PubSub消息

Python GCP云功能未正确拾取/确认PubSub消息,python,google-cloud-platform,google-cloud-functions,google-cloud-pubsub,Python,Google Cloud Platform,Google Cloud Functions,Google Cloud Pubsub,我在谷歌云平台上设置了一些数据处理工作流。这些位置处理物理地址并返回有关它们的一些度量。工作流使用云函数和子流的组合 由于工作流中有一个谷歌云功能,一些消息不会从触发流中拾取,或者多次拾取。我知道这在某种程度上是可以预料的。然而,这种情况经常发生。这足以导致某些地点的夸大10倍,而其他几个地点则没有结果 我认为回调函数没有正确地确认消息,但我不确定应该有什么不同,以获得更可靠的消息拾取和确认。如有任何建议,我们将不胜感激 检索指标的My GCP Cloud函数由PubSub流触发,并执行将数据发

我在谷歌云平台上设置了一些数据处理工作流。这些位置处理物理地址并返回有关它们的一些度量。工作流使用云函数和子流的组合

由于工作流中有一个谷歌云功能,一些消息不会从触发流中拾取,或者多次拾取。我知道这在某种程度上是可以预料的。然而,这种情况经常发生。这足以导致某些地点的夸大10倍,而其他几个地点则没有结果

我认为
回调
函数没有正确地确认消息,但我不确定应该有什么不同,以获得更可靠的消息拾取和确认。如有任何建议,我们将不胜感激

检索指标的My GCP Cloud函数由PubSub流触发,并执行将数据发送到不同PubSub流的
retrieve\u location
函数。
retrieve\u location
函数如下所示:

def retrieve_location(event, context):
    auth_flow()

    project_id = <my project id>
    subscription_name = <my subscription name>

    subscriber = pubsub_v1.SubscriberClient()

    subscription_path = subscriber.subscription_path(
        project_id, subscription_name)

    def callback(message):
        message.ack()
        message_obj = message.data
        message_dcde = message_obj.decode('utf-8')
        message_json = json.loads(message_dcde)

        get_metrics(message_json)


    subscriber.subscribe(subscription_path, callback=callback)

您不应该在云功能中设置第二个发布/订阅订阅订阅服务器,而应该创建一个订阅该主题并直接处理有效负载的订阅服务器,例如:

def get_metrics_background_函数(事件、上下文):
message_obj=event.data
消息\u dcde=消息\u对象解码('utf-8')
message_json=json.load(message_dcde)
获取度量(消息json)

看起来您可能将使用云发布/订阅触发云函数与直接通过云发布/订阅客户端库使用发布/订阅混为一谈。一般来说,你会想做一个或另一个

如果您创建的订阅是通过云函数完成的,那么您的
retrieve\u location
函数实际上并没有接收和处理消息。相反,它所做的是启动订阅者客户端,然后很快关闭,因为
subscriber.subscribe
将运行到完成,因此您的函数将完成执行

如果此函数启动的客户端与触发云函数的订阅相同,那么它实际上不会做任何事情,因为基于云函数的订阅使用该模型,而客户端库应该与该模型一起使用


您可以在
回调中直接在
检索位置
执行操作,将事件作为消息(如Dustin所述),也可以在客户端库中设置一个持久订阅者,例如在GCE上,它实例化订阅者并在其上调用
subscribe

那么,您的云功能是否由发布/订阅消息触发,导致它在不同的发布/订阅上启动订阅者?以这种方式启动发布/订阅订阅有点不寻常。@KamalAboul Hosn订阅和主题ID对于每个发布子流都是唯一的,因此不应该有交叉。但是什么是启动订户的最佳方式呢?我同意这是一种不寻常的模式。你能从高层解释一下为什么需要这样做吗?@DustinIngram从PubSub流触发函数以便拾取和处理所有消息的最佳方法是什么?我正在处理地址并检索每个地址的数据。只需将函数订阅到主题就足够了。我仍然不清楚为什么您需要在功能中使用第二个订户?我正在进行您建议的更改。在本例中,没有
message.ack()
。这不是必须的吗?这不是必须的,云函数的成功执行会产生确认发布/订阅消息的效果。这很有帮助。我有特定的订户声明,用于云功能逻辑的本地开发。删除额外设置确实有助于减少额外呼叫。然而,我现在遇到的问题是那些不存在但应该存在的呼叫。这至少解决了一个问题。这个细节对解决问题也很有帮助。感谢您提供这一见解!
def get_metrics(loc):
    <... retrieve and process data, my_data is the object that gets sent to the next stream ...>
          project_id = <my project id>
          topic_name = <my topic name>
          topic_id = <my topic id>

          publisher = pubsub_v1.PublisherClient()
          topic_path = publisher.topic_path(project_id, topic_name)

            try:
                publisher.publish(topic_path, data=my_data.encode('utf-8'))
            except Exception as exc:
                    print("topic publish failed: ", exc)