Runtime di Go

Cloud Functions supporta i seguenti runtime Go:

  • Go 1.16 (opzione consigliata)
  • Go 1.13
  • Go 1.11

Per istruzioni su come preparare la tua macchina locale per lo sviluppo di Go, consulta Configurare un ambiente di sviluppo di Go.

Per iniziare a utilizzare Go su Cloud Functions, consulta la Guida rapida.

Selezione del runtime

Puoi selezionare il runtime Go della tua funzione durante il deployment.

gcloud

Se utilizzi l'interfaccia a riga di comando di Google Cloud, puoi specificare il runtime utilizzando il parametro --runtime con il runtime Go di tua scelta (i valori supportati sono go111, go113 e go116). Ad esempio:

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

FLAGS... si riferisce agli argomenti passati durante il primo deployment della funzione. Per ulteriori informazioni sugli argomenti obbligatori e facoltativi, consulta Deployment con lo strumento gcloud.

Console

Se utilizzi Cloud Console, puoi selezionare il runtime quando crei ed esegui il deployment di una funzione. Per istruzioni dettagliate, consulta la guida rapida di Cloud Console.

Ambiente di esecuzione

L'ambiente di esecuzione include il runtime, il sistema operativo, i pacchetti e una libreria che richiama la funzione.

I runtime Go 1.11.6, Go 1.13.15 e Go 1.16.7 utilizzano un ambiente di esecuzione basato su Ubuntu 18.04. Per ulteriori informazioni, consulta Ambiente di esecuzione di Cloud Functions.

Struttura del codice sorgente

Per consentire a Cloud Functions di trovare la definizione della tua funzione, ogni runtime ha determinati requisiti di strutturazione per il codice sorgente. Per ulteriori informazioni, consulta Scrittura di Cloud Functions.

Specifica delle dipendenze

Cloud Functions in Go deve fornire tutte le sue dipendenze tramite moduli Go con un file go.mod o una directory vendor. Per ulteriori informazioni, consulta la sezione Specificare le dipendenze in Go.

Variabili di ambiente

I runtime Go 1.13 e versioni successive impostano automaticamente meno variabili di ambiente rispetto ai runtime precedenti supportati da Cloud Functions. Per i dettagli, consulta la sezione Utilizzare le variabili di ambiente.

Inizializzazione una tantum

Le tue funzioni potrebbero richiedere un'inizializzazione una tantum, ad esempio la creazione di client API e la configurazione dell'accesso al database. Puoi farlo in diversi modi:

  • Utilizza una funzione func init() per inizializzare i valori quando viene avviata una nuova istanza della funzione. Tieni presente che il codice nella funzione func init() viene eseguito prima che la funzione riceva la sua prima richiesta.

  • Utilizza la funzione sync.Once.Do() per eseguire il codice una volta per istanza di Cloud Functions. Questo è utile nei casi in cui vuoi inizializzare solo on demand anziché alla prima avvio dell'istanza della funzione. Ad esempio, potrebbe essere necessario inizializzare il client di database solo in determinate circostanze.

context.Context

Il pacchetto context di Go indica il tipo Context, che prevede scadenze, indicatori di annullamento e altri valori con ambito di richiesta nei limiti dell'API e tra i processi.

I client API che superano una determinata chiamata funzione devono essere inizializzati con un valore context.Context globale, ad esempio uno creato dalla funzione context.Background(). Per ottimizzare le prestazioni, puoi inizializzare un client in ambito globale. Questo client e il relativo contesto potrebbero rimanere attivi per tutta la durata di una determinata istanza.

Devi utilizzare il contesto di chiamata funzione solo per oggetti o operazioni che rientrano nella durata di una specifica chiamata funzione. Il contesto di chiamata potrebbe essere annullato in qualsiasi momento al termine dell'esecuzione della funzione. Di conseguenza, tutti i client inizializzati utilizzando questo contesto potrebbero essere chiusi. Il contesto di chiamata della funzione è accessibile tramite gli argomenti della funzione: di solito r.Context() per le funzioni HTTP e ctx per le funzioni in background.

Vedi il seguente codice per un esempio di utilizzo di un client 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 introduce modifiche alla gestione delle dipendenze. In particolare, ora funziona per impostazione predefinita in modalità"module-aware", il che significa che il codice sorgente dovrebbe includere un file go.mod. Le note di rilascio complete sono disponibili all'indirizzo golang.org.

Per supportare i deployment esistenti nelle versioni precedenti alla 1.16 e semplificare il percorso di migrazione:

  • Le funzioni senza go.mod continueranno a essere supportate.
  • Le funzioni con vendor e senza go.mod funzioneranno come prima per le versioni precedenti alla 1.16. Cloud Functions aggiungerà il Framework delle funzioni se non è in vendor.
  • Le funzioni con vendor e go.mod sono supportate per Go 1.14 e versioni successive, ma devono avere il framework di Functions in go.mod/vendor. In caso contrario, la build avrà esito negativo con il seguente errore:
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"`

Scopri di più su come utilizzare la directory vendor per la versione di Go specifica.