GCP 云功能何时确认发布/订阅消息?

时间:2021-01-20 12:24:08

标签: google-cloud-functions google-cloud-pubsub

我有一个从发布/订阅消息触发的云功能。此函数从不明确确认源代码中的消息。

那么,如果源代码中从未发生确认,该函数何时确认发布/订阅消息?

更新:当函数崩溃时,我知道不应发生消息确认,但日志中从未出现对该消息的新函数调用

可重现的示例

  • 创建一个名为 test_topic

    的发布订阅主题
  • 使用触发器 test_topic 创建一个名为 test_function 的云函数。给它所有的默认设置,包括不重试失败。在代码本身中,将语言设置为 python3.7,入口点为 hello_pubsub 和以下代码:

     import base64
     def hello_pubsub(event, context):
         pubsub_message = base64.b64decode(event['data']).decode('utf-8')
         print(pubsub_message)
         raise RuntimeError('error in function')
    
  • requirements.txt 保持空白

  • 进入 test_topic 并以 go 作为文本发布消息。

  • test_function 日志中会有错误。但是,只会有一个函数调用出现错误,并且即使在几天左右之后仍然如此。

2 个答案:

答案 0 :(得分:2)

如果函数正常完成,则消息为确认。如果函数错误退出,则消息为 NACK。


编辑 1

我已经使用 Go 后台功能进行了测试。您需要使用参数 --retry 部署您的云函数,以允许重试错误消息。否则,不会重试消息。

在 Go 中,这里执行重试的情况:

  • 返回错误(相当于 Java 或 Python 中的异常),日志中的状态为“错误”
  • 在日志中执行 log.Fatal()(退出函数(函数崩溃)并带有特定日志)状态“连接错误”
  • 执行显式退出,日志中的状态为“连接错误”

这里是代码(如果有兴趣)

type PubSubMessage struct {
    Data []byte `json:"data"`

}

func PubsubError(ctx context.Context, m PubSubMessage) error {

    switch string(m.Data) {
    case "ok":
        return nil
    case "error":
        return errors.New("it's an error")
    case "fatal":
        log.Fatal("crash")
    case "exit":
        os.Exit(1)
    }
    return nil
}

以及我如何部署我的云函数

gcloud beta functions deploy --runtime=go113 --trigger-topic=test-topic \
  --source=function --entry-point=PubsubError --region=us-central1 \
  --retry pubsuberror

答案 1 :(得分:0)

基于此描述: Google Cloud Pub/Sub Triggers

<块引用>

Cloud Functions 在函数调用成功后在内部确认 Pub/Sub 消息。

我确实理解文档引用,因为只有在代码执行完成且没有任何(未发现的)错误后才会进行确认。

同时,虽然执行可能仍在“进行中”,但 Pub/Sub 服务可能会决定从同一 Pub/Sub 消息触发另一个云函数(实例)。

此问题跟踪器讨论中提供了一些其他详细信息: Cloud Function explicit acknowledgement of a pubsub message

从我的角度来看,无论调用发生的“成功”还是“不成功”,云函数都将以幂等的方式开发,同时考虑到 Pub/Sub 的“至少一次交付”范式服务。换句话说,云函数的开发方式是正确处理来自一条消息的多次调用。