编写事件驱动型函数

在 Cloud Functions 中,如果您希望自动调用函数来响应云环境中发生的事件,则可以使用事件驱动型函数。

事件驱动型函数有两种实现方法。使用哪种方法取决于您选择的语言运行时,以及您使用的是 Cloud Functions(第 1 代)还是 Cloud Functions(第 2 代):

  • 在 Cloud Functions(第 2 代)中,对于所有运行时,请使用 CloudEvent 函数
  • 在 Cloud Functions(第 1 代)中:
    • 对于 Node.js、Python、Go 和 Java 运行时,请使用后台函数
    • 对于 .NET、Ruby 和 PHP 运行时,请使用 CloudEvent 函数

CloudEvent 函数

CloudEvent 函数基于 CloudEvents,后者是一种以通用方式描述事件数据的行业标准规范。如需详细了解 CloudEvents 规范,请查看 CloudEvents GitHub 代码库。CloudEvents 项目还提供一组 CloudEvents SDK,可帮助使用代码中的 CloudEvents 对象。

以下示例展示了每个运行时的基本 CloudEvent 函数源文件。如需了解源代码的位置,请参阅源目录结构

Node.js

const functions = require('@google-cloud/functions-framework');

// Register a CloudEvent function with the Functions Framework
functions.cloudEvent('myCloudEventFunction', cloudEvent => {
  // Your code here
  // Access the CloudEvent data payload via cloudEvent.data
});

在 Node.js 中,您需要向 Node.js 版 Functions 框架注册 CloudEvent 处理程序函数。您的处理程序函数必须接受 CloudEvent 对象作为参数。

函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 myCloudEventFunction

Python

import functions_framework

# Register a CloudEvent function with the Functions Framework
@functions_framework.cloud_event
def my_cloudevent_function(cloud_event):
  # Your code here
  # Access the CloudEvent data payload via cloud_event.data

在 Python 中,您需要向 Python 版 Functions 框架注册 CloudEvent 处理程序函数。您的处理程序函数必须接受 CloudEvent 对象作为参数。

函数入口点是向 Functions 框架注册的处理程序函数的名称。在此示例中,入口点为 my_cloudevent_function

Go

package mycloudeventfunction

import (
    "context"

    "github.com/GoogleCloudPlatform/functions-framework-go/functions"
    "github.com/cloudevents/sdk-go/v2/event"
)

func init() {
    // Register a CloudEvent function with the Functions Framework
    functions.CloudEvent("MyCloudEventFunction", myCloudEventFunction)
}

// Function myCloudEventFunction accepts and handles a CloudEvent object
func myCloudEventFunction(ctx context.Context, e event.Event) error {
    // Your code here
    // Access the CloudEvent data payload via e.Data() or e.DataAs(...)

    // Return nil if no error occurred
    return nil
}

在 Go 中,您需要向 Go 版 Functions 框架注册 CloudEvent 处理程序函数。您的处理程序函数必须接受 CloudEvents event.Event对象作为参数。

函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 MyCloudEventFunction

Java

package mycloudeventfunction;

import com.google.cloud.functions.CloudEventsFunction;
import io.cloudevents.CloudEvent;

// Define a class that implements the CloudEventsFunction interface
public class MyCloudEventFunction implements CloudEventsFunction {
  // Implement the accept() method to handle CloudEvents
  @Override
  public void accept(CloudEvent event) {
    // Your code here
    // Access the CloudEvent data payload via event.getData()
    // To get the data payload as a JSON string, use:
    // new String(event.getData().toBytes())
  }
}

在 Java 中,您需要使用 Functions Framework Java API 通过 CloudEventsFunction 接口实现 CloudEvent 处理程序类。accept() 方法必须接受 CloudEvent 对象作为参数并对事件执行任何处理。

函数入口点是 CloudEvent 处理程序类的完全限定名称,包括软件包名称。在此示例中,入口点为 mycloudeventfunction.MyCloudEventFunction

C#

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using System.Threading;
using System.Threading.Tasks;

namespace MyProject
{
    // Define a class that implements the ICloudEventFunction<T> interface
    public class MyCloudEventFunction : ICloudEventFunction<CloudEventDataType>
    {
        // Implement the HandleAsync() method to handle CloudEvents
        public Task HandleAsync(CloudEvent cloudEvent, CloudEventDataType data, CancellationToken cancellationToken)
        {
            // Your code here
            // The data argument represents the CloudEvent data payload

            // Signal function completion
            return Task.CompletedTask;
        }
    }
}

在 .NET 运行时中,您需要使用 .NET 版 Functions 框架通过 ICloudEventFunction<T> 接口实现 CloudEvent 处理程序类。HandleAsync() 方法接受 CloudEvent 对象和关联的 CloudEvent 数据载荷作为参数。

CloudEvent 数据载荷参数的类型(在上面的示例中显示为 CloudEventDataType)必须与函数处理的事件类型对应。Google CloudEvents .NET 库为 Google 支持的各种事件提供了数据类型。

函数入口点是 CloudEvent 处理程序类的完全限定名称,包括命名空间。在此示例中,入口点为 MyProject.MyCloudEventFunction

Ruby

require "functions_framework"

# Register a CloudEvent function with the Functions Framework
FunctionsFramework.cloud_event "my_cloudevent_function" do |cloud_event|
  # Your code here
  # Access the CloudEvent data payload via cloud_event.data
end

在 Ruby 中,您需要向 Ruby 版 Functions 框架注册 CloudEvent 处理程序函数。您的处理程序函数必须接受 CloudEvents Event 对象作为参数。

函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 my_cloudevent_function

PHP

<?php

use CloudEvents\V1\CloudEventInterface;
use Google\CloudFunctions\FunctionsFramework;

// Register a CloudEvent function with the Functions Framework
FunctionsFramework::cloudEvent('myCloudEventFunction', 'myCloudEventHandler');

// Define your CloudEvent handler
function myCloudEventHandler(CloudEventInterface $event): void
{
    // Your code here
    // Access the CloudEvent data payload via $event->getData()
}

在 PHP 中,您需要向 PHP 版 Functions 框架注册 CloudEvent 处理程序函数。您的处理程序函数必须接受符合 CloudEventInterface 接口的参数。

函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 myCloudEventFunction

对于 CloudEvent 函数,事件数据会以 CloudEvents 格式传递给函数,并且 CloudEvent 数据载荷与触发函数的事件类型对应。如需了解受支持的触发器、事件类型和关联的事件数据格式,请参阅 Cloud Functions 触发器

Google 事件代码库包含用于处理 Google 发出的 CloudEvents 的资源。

后台函数

Cloud Functions(第 1 代)Node.js、Python、Go 和 Java 运行时中的事件驱动型函数需要与 CloudEvent 函数不同的参数。这种旧版事件驱动型函数称为“后台函数”

以下示例展示了每个运行时的基本后台函数源文件。如需了解源代码的位置,请参阅源目录结构

Node.js

// Define and export an event handler
exports.myBackgroundFunction = (eventData, context, callback) => {
  // Your code here
  // The eventData argument represents the event data payload

  // Optionally signal function completion:
  callback();
};

在 Node.js 中,您需要定义和导出处理事件数据的函数。Cloud Functions 将处理程序函数传递给以下参数:

  • eventData:表示事件数据载荷的对象。其格式取决于事件类型。
  • context:包含事件元数据的对象。
  • callback:您可以调用的可选函数,用于指示函数已完成。此回调的第一个参数会被解释为指示错误。不传递任何参数或传递值为 null 的第一个参数可以指示成功。

函数入口点是导出的事件处理程序的名称。在此示例中,入口点为 myBackgroundFunction

Python

# Define an event handler
def my_background_function(event_data, context):
  # Your code here
  # The event_data argument represents the event data payload

在 Python 中,您需要定义一个处理事件数据的函数。Cloud Functions 将处理程序函数传递给以下参数:

  • event_data:表示事件数据载荷的字典。其格式取决于事件类型。
  • context:包含事件元数据的对象。

函数入口点是处理程序函数的名称。在此示例中,入口点为 my_background_function

Go

package mybackgroundfunction

import (
    "context"
)

// Function MyBackgroundFunction accepts and handles event data
func MyBackgroundFunction(ctx context.Context, e EventDataType) error {
    // Your code here
    // The argument e represents the event data payload

    // Return nil if no error occurred
    return nil
}

在 Go 中,您需要定义一个处理事件数据的导出函数。Cloud Functions 将处理程序函数传递给以下参数:

  • ctx:包含事件元数据的 context.Context 对象。您可以使用 cloud.google.com/go/functions/metadata 软件包检索该元数据。
  • e:表示事件数据载荷的对象。它的类型(在上面的示例中显示为 EventDataType)必须是与函数处理的事件类型对应的结构体。事件数据载荷使用 json.Unmarshal() 取消封送至结构体。

函数入口点是导出的事件处理程序的名称。在此示例中,入口点为 MyBackgroundFunction

Java

package mybackgroundfunction;

import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;

// Define a class that implements the BackgroundFunction<T> interface
public class MyBackgroundFunction implements BackgroundFunction<EventDataType> {
  // Implement the accept() method to handle events
  @Override
  public void accept(EventDataType eventData, Context context) {
    // Your code here
    // The eventData argument represents the event data payload
  }
}

在 Java 中,您需要使用 Functions Framework Java API 通过 BackgroundFunction<T> 接口实现事件处理程序类。accept() 方法接受事件数据载荷和包含事件元数据的 Context 对象作为参数。

事件数据载荷参数的类型(在上面的示例中显示为 EventDataType)必须与函数处理的事件类型对应。事件数据载荷使用 Gson.fromJson() 反序列化为此类的一个实例。

函数入口点是事件处理程序类的完全限定名称,包括软件包名称。在此示例中,入口点为 mybackgroundfunction.MyBackgroundFunction

对于后台函数,事件数据载荷会以与触发函数的事件类型对应的格式直接传递给函数。如需了解支持的触发器、事件类型和关联的事件数据格式,请参阅 Cloud Functions(第 1 代)中支持的触发器

函数终止

当函数返回时,Cloud Functions 认为事件驱动型函数执行完成。如果函数创建了后台任务(例如使用线程、future、JavaScript Promise 对象、回调或系统进程),您必须先终止这些任务或以其他方式解决这些任务,然后再从函数返回。在函数返回之前未终止的任何任务都可能无法完成,并可能导致未定义的行为。

自动重试

事件驱动型函数可以配置为自动重试失败的调用。如需了解详情,请参阅重试事件驱动型函数

后续步骤