Cloud Storage 教程(第 1 代)

本简易教程演示了如何使用 Cloud Storage 触发器编写、部署和触发 Cloud Run functions 事件驱动函数来响应 Cloud Storage 事件。

如果您要查找使用 Cloud Storage 本身的代码示例,请访问 Google Cloud 示例浏览器

准备应用

  1. 创建一个 Cloud Storage 存储分区以向其中上传测试文件,其中,YOUR_TRIGGER_BUCKET_NAME 是全局唯一的存储分区名称:

    gcloud storage buckets create gs://YOUR_TRIGGER_BUCKET_NAME
  2. 将示例应用代码库克隆到本地机器:

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    或者,您也可以下载该示例的 zip 文件并将其解压缩。

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    或者,您也可以下载该示例的 zip 文件并将其解压缩。

    Go

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git

    或者,您也可以下载该示例的 zip 文件并将其解压缩。

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    或者,您也可以下载该示例的 zip 文件并将其解压缩。

    Ruby

    git clone https://github.com/GoogleCloudPlatform/ruby-docs-samples.git

    或者,您也可以下载该示例的 zip 文件并将其解压缩。

  3. 切换到包含 Cloud Run functions 函数示例代码的目录:

    Node.js

    cd nodejs-docs-samples/functions/helloworld/

    Python

    cd python-docs-samples/functions/helloworld/

    Go

    cd golang-samples/functions/helloworld/

    Java

    cd java-docs-samples/functions/helloworld/hello-gcs/

    Ruby

    cd ruby-docs-samples/functions/helloworld/storage/

部署和触发函数

Cloud Storage 函数基于 Cloud Storage 发出的 Pub/Sub 通知,并且支持类似事件类型:

以下部分介绍如何为每种类型的事件部署和触发函数。

完成对象创建

Cloud Storage 对象的“写入”成功完成后,“完成对象创建”事件会被触发。具体而言,这意味着创建新对象或覆盖现有对象会触发此事件。此触发器会忽略归档操作和元数据更新操作。

完成对象创建:部署函数

查看处理 Cloud Storage 事件的示例函数:

Node.js

/**
 * Generic background Cloud Function to be triggered by Cloud Storage.
 * This sample works for all Cloud Storage CRUD operations.
 *
 * @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,
       and works for all Cloud Storage CRUD operations.
    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 Cloud Logging
    """

    print(f"Event ID: {context.event_id}")
    print(f"Event type: {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(ny) GCS event.
func HelloGCS(ctx context.Context, e GCSEvent) error {
	meta, err := metadata.FromContext(ctx)
	if err != nil {
		return fmt.Errorf("metadata.FromContext: %w", 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;

/**
 * Example Cloud Storage-triggered function.
 * This function can process any event from Cloud Storage.
 */
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());
  }
}

Ruby

require "functions_framework"

FunctionsFramework.cloud_event "hello_gcs" do |event|
  # This function supports all Cloud Storage events.
  # The `event` parameter is a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  payload = event.data

  logger.info "Event: #{event.id}"
  logger.info "Event Type: #{event.type}"
  logger.info "Bucket: #{payload['bucket']}"
  logger.info "File: #{payload['name']}"
  logger.info "Metageneration: #{payload['metageneration']}"
  logger.info "Created: #{payload['timeCreated']}"
  logger.info "Updated: #{payload['updated']}"
end

如需部署该函数,请在示例代码所在的目录中运行以下命令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 标志可以指定支持的 Node.js 版本的运行时 ID 来运行您的函数。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 标志可以指定支持的 Python 版本的运行时 ID 来运行您的函数。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 标志可以指定支持的 Go 版本的运行时 ID 来运行您的函数。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.finalize

使用 --runtime 标志可以指定支持的 Java 版本的运行时 ID 来运行您的函数。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.finalize

使用 --runtime 标志可以指定支持的 Ruby 版本的运行时 ID 来运行您的函数。

其中,YOUR_TRIGGER_BUCKET_NAME 是触发函数的 Cloud Storage 存储分区的名称。

完成对象创建:触发函数

要触发函数,请执行以下操作:

  1. 在示例代码所在的目录中创建一个空 gcf-test.txt 文件。

  2. 将该文件上传到 Cloud Storage 以触发函数:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中,YOUR_TRIGGER_BUCKET_NAME 是您要向其中上传测试文件的 Cloud Storage 存储桶的名称。

  3. 检查日志以确保执行已完成:

    gcloud functions logs read --limit 50
    

对象删除

当对象被软删除时,系统会触发对象删除事件。如果在未启用对象版本控制的存储桶中覆盖或删除对象,则会发生这种情况。通过指定对象的世代编号来删除对象也会导致相应对象被软删除。

对象删除:部署函数

使用与“完成创建”示例相同的示例代码,以对象删除作为触发器事件来部署函数。在示例代码所在的目录中运行以下命令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 标志可以指定支持的 Node.js 版本的运行时 ID 来运行您的函数。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 标志可以指定支持的 Python 版本的运行时 ID 来运行您的函数。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 标志可以指定支持的 Go 版本的运行时 ID 来运行您的函数。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.delete

使用 --runtime 标志可以指定支持的 Java 版本的运行时 ID 来运行您的函数。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.delete

使用 --runtime 标志可以指定支持的 Ruby 版本的运行时 ID 来运行您的函数。

其中,YOUR_TRIGGER_BUCKET_NAME 是触发函数的 Cloud Storage 存储分区的名称。

对象删除:触发函数

要触发函数,请执行以下操作:

  1. 在示例代码所在的目录中创建一个空 gcf-test.txt 文件。

  2. 确保您的存储分区未启用版本控制:

    gcloud storage buckets update gs://YOUR_TRIGGER_BUCKET_NAME --no-versioning
  3. 将该文件上传到 Cloud Storage:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中,YOUR_TRIGGER_BUCKET_NAME 是您要向其中上传测试文件的 Cloud Storage 存储桶的名称。此时,函数应该尚未执行。

  4. 删除该文件以触发函数:

    gcloud storage rm gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
  5. 检查日志以确保执行已完成:

    gcloud functions logs read --limit 50
    

请注意,函数可能需要一些时间才能执行完毕。

对象归档

当对象的当前版本变为非当前版本时,系统会触发对象归档事件。如果在启用了对象版本控制的存储桶中覆盖或删除对象,则会发生这种情况。

对象归档:部署函数

使用与“完成创建”示例相同的示例代码,以对象归档作为触发器事件来部署函数。在示例代码所在的目录中运行以下命令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 标志可以指定支持的 Node.js 版本的运行时 ID 来运行您的函数。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 标志可以指定支持的 Python 版本的运行时 ID 来运行您的函数。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 标志可以指定支持的 Go 版本的运行时 ID 来运行您的函数。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.archive

使用 --runtime 标志可以指定支持的 Java 版本的运行时 ID 来运行您的函数。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.archive

使用 --runtime 标志可以指定支持的 Ruby 版本的运行时 ID 来运行您的函数。

其中,YOUR_TRIGGER_BUCKET_NAME 是触发函数的 Cloud Storage 存储分区的名称。

对象归档:触发函数

要触发函数,请执行以下操作:

  1. 在示例代码所在的目录中创建一个空 gcf-test.txt 文件。

  2. 确保您的存储分区已启用版本控制:

    gcloud storage buckets update gs://YOUR_TRIGGER_BUCKET_NAME --versioning
  3. 将该文件上传到 Cloud Storage:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中,YOUR_TRIGGER_BUCKET_NAME 是您要向其中上传测试文件的 Cloud Storage 存储桶的名称。此时,函数应该尚未执行。

  4. 归档该文件以触发函数:

    gcloud storage rm gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt
  5. 查看日志以确保执行已完成:

    gcloud functions logs read --limit 50
    

对象元数据更新

当现有对象的元数据更新时,元数据更新事件会被触发。

对象元数据更新:部署函数

使用与“完成创建”示例相同的示例代码,以元数据更新作为触发器事件来部署函数。在示例代码所在的目录中运行以下命令:

Node.js

gcloud functions deploy helloGCS \
--runtime nodejs22 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 标志可以指定支持的 Node.js 版本的运行时 ID 来运行您的函数。

Python

gcloud functions deploy hello_gcs \
--runtime python312 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 标志可以指定支持的 Python 版本的运行时 ID 来运行您的函数。

Go

gcloud functions deploy HelloGCS \
--runtime go121 \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 标志可以指定支持的 Go 版本的运行时 ID 来运行您的函数。

Java

gcloud functions deploy java-gcs-function \
--entry-point functions.HelloGcs \
--runtime java17 \
--memory 512MB \
--trigger-resource YOUR_TRIGGER_BUCKET_NAME \
--trigger-event google.storage.object.metadataUpdate

使用 --runtime 标志可以指定支持的 Java 版本的运行时 ID 来运行您的函数。

Ruby

gcloud functions deploy hello_gcs --runtime ruby33 \
-
-trigger-resource YOUR_TRIGGER_BUCKET_NAME \
-
-trigger-event google.storage.object.metadataUpdate

使用 --runtime 标志可以指定支持的 Ruby 版本的运行时 ID 来运行您的函数。

其中,YOUR_TRIGGER_BUCKET_NAME 是触发函数的 Cloud Storage 存储分区的名称。

对象元数据更新:触发函数

要触发函数,请执行以下操作:

  1. 在示例代码所在的目录中创建一个空 gcf-test.txt 文件。

  2. 确保您的存储分区未启用版本控制:

    gcloud storage buckets update gs://YOUR_TRIGGER_BUCKET_NAME --no-versioning
  3. 将该文件上传到 Cloud Storage:

    gcloud storage cp gcf-test.txt gs://YOUR_TRIGGER_BUCKET_NAME

    其中,YOUR_TRIGGER_BUCKET_NAME 是您要向其中上传测试文件的 Cloud Storage 存储桶的名称。此时,函数应该尚未执行。

  4. 更新该文件的元数据:

    gcloud storage objects update gs://YOUR_TRIGGER_BUCKET_NAME/gcf-test.txt --content-type=text/plain
  5. 查看日志以确保执行已完成:

    gcloud functions logs read --limit 50