后台函数

后台函数是一种事件驱动的函数类型。Node.js、Go、Python 和 Java 均支持此函数。

如果您要在响应事件(例如 Pub/Sub 主题中收到消息、Cloud Storage 存储分区发生更改或 Firebase 事件)时间接调用 Cloud Functions 函数,则可以使用后台函数。

如需了解如何重试后台函数,请参阅重试事件驱动的函数

支持运行时

以下运行时支持后台函数:

语言 版本
Node.js 全部
Python 全部
Go 全部
Java 全部

用法示例

以下示例展示了如何处理 Pub/Sub 和 Cloud Storage 中的事件。如需详细了解如何处理不同来源的事件,请参阅调用 Cloud Functions 函数

Pub/Sub 示例

此示例展示了一个由 Pub/Sub 事件触发的 Cloud Functions 函数。每次有消息发布到 Pub/Sub 主题时,系统都会调用此函数,使用从消息中提取的数据向日志中写入一句问候语。

Node.js

/**
 * Background Cloud Function to be triggered by Pub/Sub.
 * This function is exported by index.js, and executed when
 * the trigger topic receives a message.
 *
 * @param {object} message The Pub/Sub message.
 * @param {object} context The event metadata.
 */
exports.helloPubSub = (message, context) => {
  const name = message.data
    ? Buffer.from(message.data, 'base64').toString()
    : 'World';

  console.log(`Hello, ${name}!`);
};

Python

def hello_pubsub(event, context):
    """Background Cloud Function to be triggered by Pub/Sub.
    Args:
         event (dict):  The dictionary with data specific to this type of
                        event. The `@type` field maps to
                         `type.googleapis.com/google.pubsub.v1.PubsubMessage`.
                        The `data` field maps to the PubsubMessage data
                        in a base64-encoded string. The `attributes` field maps
                        to the PubsubMessage attributes if any is present.
         context (google.cloud.functions.Context): Metadata of triggering event
                        including `event_id` which maps to the PubsubMessage
                        messageId, `timestamp` which maps to the PubsubMessage
                        publishTime, `event_type` which maps to
                        `google.pubsub.topic.publish`, and `resource` which is
                        a dictionary that describes the service API endpoint
                        pubsub.googleapis.com, the triggering topic's name, and
                        the triggering event type
                        `type.googleapis.com/google.pubsub.v1.PubsubMessage`.
    Returns:
        None. The output is written to Cloud Logging.
    """
    import base64

    print("""This Function was triggered by messageId {} published at {} to {}
    """.format(context.event_id, context.timestamp, context.resource["name"]))

    if 'data' in event:
        name = base64.b64decode(event['data']).decode('utf-8')
    else:
        name = 'World'
    print('Hello {}!'.format(name))

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"log"
)

// PubSubMessage is the payload of a Pub/Sub event.
// See the documentation for more details:
// https://cloud.google.com/pubsub/docs/reference/rest/v1/PubsubMessage
type PubSubMessage struct {
	Data []byte `json:"data"`
}

// HelloPubSub consumes a Pub/Sub message.
func HelloPubSub(ctx context.Context, m PubSubMessage) error {
	name := string(m.Data) // Automatically decoded from base64.
	if name == "" {
		name = "World"
	}
	log.Printf("Hello, %s!", name)
	return nil
}

Java


import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import com.google.events.cloud.pubsub.v1.Message;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.logging.Level;
import java.util.logging.Logger;

public class HelloPubSub implements BackgroundFunction<Message> {
  private static final Logger logger = Logger.getLogger(HelloPubSub.class.getName());

  @Override
  public void accept(Message message, Context context) {
    String name = "world";
    if (message != null && message.getData() != null) {
      name = new String(
          Base64.getDecoder().decode(message.getData().getBytes(StandardCharsets.UTF_8)),
          StandardCharsets.UTF_8);
    }
    logger.info(String.format("Hello %s!", name));
    return;
  }
}

如需详细了解如何部署由 Pub/Sub 事件触发的 Cloud Functions 函数,请参阅 Pub/Sub 触发器Pub/Sub 教程

Cloud Storage 示例

此示例展示了一个由 Cloud Storage 事件触发的 Cloud Functions 函数。 每当 Cloud Storage 存储分区中创建了对象时,系统都会调用该函数,并向日志中写入一条有关这项更改的消息。

Node.js

/**
 * Generic background Cloud Function to be triggered by Cloud Storage.
 *
 * @param {object} file The Cloud Storage file metadata.
 * @param {object} context The event metadata.
 */
exports.helloGCS = (file, context) => {
  console.log(`  Event: ${context.eventId}`);
  console.log(`  Event Type: ${context.eventType}`);
  console.log(`  Bucket: ${file.bucket}`);
  console.log(`  File: ${file.name}`);
  console.log(`  Metageneration: ${file.metageneration}`);
  console.log(`  Created: ${file.timeCreated}`);
  console.log(`  Updated: ${file.updated}`);
};

Python

def hello_gcs(event, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed.

    Args:
        event (dict):  The dictionary with data specific to this type of event.
                       The `data` field contains a description of the event in
                       the Cloud Storage `object` format described here:
                       https://cloud.google.com/storage/docs/json_api/v1/objects#resource
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Stackdriver Logging
    """

    print('Event ID: {}'.format(context.event_id))
    print('Event type: {}'.format(context.event_type))
    print('Bucket: {}'.format(event['bucket']))
    print('File: {}'.format(event['name']))
    print('Metageneration: {}'.format(event['metageneration']))
    print('Created: {}'.format(event['timeCreated']))
    print('Updated: {}'.format(event['updated']))

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/functions/metadata"
)

// GCSEvent is the payload of a GCS event.
type GCSEvent struct {
	Kind                    string                 `json:"kind"`
	ID                      string                 `json:"id"`
	SelfLink                string                 `json:"selfLink"`
	Name                    string                 `json:"name"`
	Bucket                  string                 `json:"bucket"`
	Generation              string                 `json:"generation"`
	Metageneration          string                 `json:"metageneration"`
	ContentType             string                 `json:"contentType"`
	TimeCreated             time.Time              `json:"timeCreated"`
	Updated                 time.Time              `json:"updated"`
	TemporaryHold           bool                   `json:"temporaryHold"`
	EventBasedHold          bool                   `json:"eventBasedHold"`
	RetentionExpirationTime time.Time              `json:"retentionExpirationTime"`
	StorageClass            string                 `json:"storageClass"`
	TimeStorageClassUpdated time.Time              `json:"timeStorageClassUpdated"`
	Size                    string                 `json:"size"`
	MD5Hash                 string                 `json:"md5Hash"`
	MediaLink               string                 `json:"mediaLink"`
	ContentEncoding         string                 `json:"contentEncoding"`
	ContentDisposition      string                 `json:"contentDisposition"`
	CacheControl            string                 `json:"cacheControl"`
	Metadata                map[string]interface{} `json:"metadata"`
	CRC32C                  string                 `json:"crc32c"`
	ComponentCount          int                    `json:"componentCount"`
	Etag                    string                 `json:"etag"`
	CustomerEncryption      struct {
		EncryptionAlgorithm string `json:"encryptionAlgorithm"`
		KeySha256           string `json:"keySha256"`
	}
	KMSKeyName    string `json:"kmsKeyName"`
	ResourceState string `json:"resourceState"`
}

// HelloGCS consumes a GCS event.
func HelloGCS(ctx context.Context, e GCSEvent) error {
	meta, err := metadata.FromContext(ctx)
	if err != nil {
		return fmt.Errorf("metadata.FromContext: %v", err)
	}
	log.Printf("Event ID: %v\n", meta.EventID)
	log.Printf("Event type: %v\n", meta.EventType)
	log.Printf("Bucket: %v\n", e.Bucket)
	log.Printf("File: %v\n", e.Name)
	log.Printf("Metageneration: %v\n", e.Metageneration)
	log.Printf("Created: %v\n", e.TimeCreated)
	log.Printf("Updated: %v\n", e.Updated)
	return nil
}

Java

import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import functions.eventpojos.GcsEvent;
import java.util.logging.Logger;

public class HelloGcs implements BackgroundFunction<GcsEvent> {
  private static final Logger logger = Logger.getLogger(HelloGcs.class.getName());

  @Override
  public void accept(GcsEvent event, Context context) {
    logger.info("Event: " + context.eventId());
    logger.info("Event Type: " + context.eventType());
    logger.info("Bucket: " + event.getBucket());
    logger.info("File: " + event.getName());
    logger.info("Metageneration: " + event.getMetageneration());
    logger.info("Created: " + event.getTimeCreated());
    logger.info("Updated: " + event.getUpdated());
  }
}

如需详细了解如何部署由 Cloud Storage 事件触发的 Cloud Functions 函数,请参阅 Cloud Storage 触发器Cloud Storage 教程

函数参数

一些参数会传递至后台函数,其中包含与触发函数执行的事件相关联的数据。下面介绍后台函数的参数:

Node.js

在 Node.js 运行时中,系统向您的函数传递参数 (data, context, callback)

属性 说明 类型
data 事件的数据对象。其类型取决于具体事件。 对象
context 事件的上下文对象。 对象
context.eventId 事件的唯一 ID。例如:"70172329041928" 字符串
context.timestamp 此事件的创建日期/时间。例如:"2018-04-09T07:56:12.975Z" 字符串 (ISO 8601)
context.eventType 事件的类型。例如:"google.pubsub.topic.publish" 字符串
context.resource 发出事件的资源。 对象
callback

用于发出信号来指示函数的执行已完成的回调函数。 遵循“errback”约定,该约定将第一个参数解释为错误:


callback();                    // Success
callback(null, 'Success!');    // Success
callback(1);                   // Error
callback(new Error('Failed')); // Error
函数

Python

在 Python 运行时中,系统向您的函数传递参数 (data, context)

属性 说明 类型
data 包含事件数据的字典。其格式取决于具体事件。 Cloud Storage 对象PubsubMessage
context 事件的上下文对象。 Context
context.event_id 事件的唯一 ID。例如:"70172329041928" 字符串
context.timestamp 此事件的创建日期/时间。例如:"2018-04-09T07:56:12.975Z" 字符串 (ISO 8601)
context.event_type 事件的类型。例如:"google.pubsub.topic.publish" 字符串
context.resource 发出事件的资源。 字符串

Go

在 Go 运行时中,系统向您的函数传递参数 (ctx, Event)

属性 说明 类型
ctx 一个 context.Context 值,其中包含事件的相关元数据。您可以使用 cloud.google.com/go/functions/metadata 软件包检索该元数据。 context.Context
Event

一种 struct(其类型由您定义),系统将使用 json.Unmarshal() 将事件载荷取消封送至此属性。事件载荷取决于注册了函数的触发器。

您在代码中提供的 struct 定义必须与事件类型的结构相对应。每个事件的结构均记录在相应事件的触发器页面上。

请注意,struct 并不需要定义该载荷中包含的每个字段。您可能只想在函数中使用某些特定字段,在这种情况下,您只需要在 struct 中定义这些字段。您还可以使用字段上的 JSON 标记重命名该字段(例如,在 JSON 字段名称包含下划线时)。

用户定义的 struct

Java

在 Java 运行时中,系统向您的函数传递参数 (event, context)。后台函数有两种类型:BackgroundFunction<T>RawBackgroundFunction

属性 说明 类型
event 事件的载荷。载荷的内容取决于注册了函数的触发器。

对于 BackgroundFunction<T>,此参数的类型为 T,是一个由用户定义的类。使用 Gson.fromJson 将事件的 JSON 载荷反序列化为此类的一个实例。

对于 RawBackgroundFunction,此参数的类型为 String,是事件的 JSON 载荷。
由用户定义或 String
context 一个只读 Context 对象,其中包含有关事件的元数据。 Context

事件数据取决于注册了函数的触发器,例如 Pub/Sub 或 Cloud Storage。对于直接触发的函数(使用 gcloud functions call 命令触发),事件数据包含您直接发送的消息。

终止后台函数

如果一个函数创建了后台任务(例如线程、future、Node.js Promise 对象、回调或系统进程),则必须先终止这些任务或以其他方式对其进行解析,然后再从函数返回。在从特定执行返回之前未终止的任何任务可能不会完成,还可能导致出现未定义的行为。

后续步骤