Go 运行时

Cloud Functions 支持以下 Go 运行时:

  • Go 1.16(推荐)
  • Go 1.13
  • Go 1.11

如需了解如何为 Go 开发准备本地机器,请参阅设置 Go 开发环境

要开始在 Cloud Functions 上使用 Go,请参阅快速入门

选择运行时

您可以在部署期间为您的函数选择 Go 运行时。

gcloud

如果您使用 Google Cloud CLI,可以用 --runtime 参数指定 Go 运行时(支持的值为 go111go113go116)。例如:

gcloud functions deploy FUNCTION_NAME --runtime go116 FLAGS...

FLAGS... 是指在第一次部署您的函数期间传递的参数。如需详细了解必需参数和可选参数,请参阅使用 gcloud 工具进行部署

控制台

如果您使用的是 Cloud Console,则可以在创建和部署函数时选择运行时。 如需详细说明,请参阅 Cloud Console 快速入门

执行环境

执行环境包括运行时、操作系统、软件包和调用函数的库。

Go 1.11.6、Go 1.13.15 和 Go 1.16.7 运行时使用基于 Ubuntu 18.04 的执行环境。如需了解详情,请参阅 Cloud Functions 函数执行环境

源代码结构

要让 Cloud Functions 找到您的函数定义,每个运行时都对您的源代码有一定的结构要求。如需了解详情,请参阅编写 Cloud Functions 函数

指定依赖项

Go 中的 Cloud Functions 函数必须通过包含 go.mod 文件的 Go 模块或 vendor 目录提供其所有依赖项。如需了解详情,请参阅指定 Go 依赖项

环境变量

与 Cloud Functions 支持的过往运行时相比,Go 1.13+ 运行时自动设置的环境变量较少。如需了解详情,请参阅使用环境变量

一次性初始化

您的函数可能需要进行一次性初始化,例如创建 API 客户端和配置数据库访问。您可以通过多种方式执行此操作:

  • 使用 func init() 函数在您的函数的新实例启动时初始化值。请注意,func init() 函数中的代码在您的函数收到其第一个请求之前运行。

  • 使用 sync.Once.Do() 函数为每个 Cloud Functions 函数实例运行一次代码。如果您只想按需初始化函数实例,而不是在函数实例首次启动时进行初始化,这会非常有用。例如,您可能只需要在某些情况下初始化数据库客户端。

context.Context

Go 的 context 软件包定义了 Context 类型,该类型跨 API 边界和在进程之间传递截止时限、取消信号以及其他请求范围的值。

超出给定函数调用存在时间的 API 客户端应使用全局 context.Context 值(例如由 context.Background() 函数创建的此类值)进行初始化。要优化性能,您可以在全局范围内初始化客户端。此客户端及其上下文可能会在给定函数实例的整个生命周期内持续存在。

对于属于特定函数调用的生命周期内的对象或操作,您只应使用函数调用上下文。 此调用上下文可能会在函数完成执行后随时被取消,这意味着使用此上下文初始化的任何客户端都可能被关闭。您可以通过函数的参数访问函数调用上下文:通常,HTTP 函数的参数是 r.Context(),后台函数的参数是 ctx

如需查看使用 Pub/Sub 客户端的示例,请参阅以下代码:


// Package contexttip is an example of how to use Pub/Sub and context.Context in
// a Cloud Function.
package contexttip

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	"cloud.google.com/go/pubsub"
)

// GOOGLE_CLOUD_PROJECT is a user-set environment variable.
var projectID = os.Getenv("GOOGLE_CLOUD_PROJECT")

// client is a global Pub/Sub client, initialized once per instance.
var client *pubsub.Client

func init() {
	// err is pre-declared to avoid shadowing client.
	var err error

	// client is initialized with context.Background() because it should
	// persist between function invocations.
	client, err = pubsub.NewClient(context.Background(), projectID)
	if err != nil {
		log.Fatalf("pubsub.NewClient: %v", err)
	}
}

type publishRequest struct {
	Topic   string `json:"topic"`
	Message string `json:"message"`
}

// PublishMessage publishes a message to Pub/Sub. PublishMessage only works
// with topics that already exist.
func PublishMessage(w http.ResponseWriter, r *http.Request) {
	// Parse the request body to get the topic name and message.
	p := publishRequest{}

	if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
		log.Printf("json.NewDecoder: %v", err)
		http.Error(w, "Error parsing request", http.StatusBadRequest)
		return
	}

	if p.Topic == "" || p.Message == "" {
		s := "missing 'topic' or 'message' parameter"
		log.Println(s)
		http.Error(w, s, http.StatusBadRequest)
		return
	}

	m := &pubsub.Message{
		Data: []byte(p.Message),
	}
	// Publish and Get use r.Context() because they are only needed for this
	// function invocation. If this were a background function, they would use
	// the ctx passed as an argument.
	id, err := client.Topic(p.Topic).Publish(r.Context(), m).Get(r.Context())
	if err != nil {
		log.Printf("topic(%s).Publish.Get: %v", p.Topic, err)
		http.Error(w, "Error publishing message", http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "Message published: %v", id)
}

Go 1.16

Go 1.16 引入了依赖项管理更改。值得注意的是,它现在默认在“模块感知”模式下运行,这意味着源代码应包含 go.mod 文件。如需查看完整的版本说明,请访问 golang.org

如要支持版本低于 1.16 的现有部署并简化迁移路径,请执行以下操作:

  • 没有 go.mod 的函数将继续受支持。
  • 带有 vendor 且没有 go.mod 的函数适用于 1.16 版之前的版本。如果 Functions 框架不在 vendor 中,则该函数将会添加。
  • Go 1.14+ 支持具有 vendorgo.mod 的函数,但它们必须具有 go.mod/vendor 中的 Functions 框架。否则,构建将失败并显示以下错误:
vendored dependencies must include "github.com/GoogleCloudPlatform/functions-framework-go";
if your function does not depend on the module, please add a blank import:
`_ "github.com/GoogleCloudPlatform/functions-framework-go"`

详细了解如何为特定 Go 版本使用 vendor 目录