Ambiente di esecuzione di Cloud Functions

Cloud Functions viene eseguito in un ambiente serverless completamente gestito in cui Google gestisce infrastruttura, sistemi operativi e ambienti di runtime. Ogni funzione viene eseguita nel proprio contesto di esecuzione sicura e isolato, scala automaticamente e ha un ciclo di vita indipendente dalle altre funzioni.

Runtime

Cloud Functions supporta più runtime dei linguaggi. Ciascuno contiene un set standard di pacchetti di sistema, nonché gli strumenti e le librerie necessari per quel linguaggio. Avrai bisogno del valore ID runtime se esegui il deployment delle funzioni dalla riga di comando o tramite Terraform.

Gli aggiornamenti di sicurezza e manutenzione sono disponibili per tutti gli ambienti di esecuzione di 1a e 2ª generazione. Questi aggiornamenti vengono applicati automaticamente o manualmente, a seconda dell'ambiente e della configurazione. Per ulteriori informazioni sugli aggiornamenti dell'ambiente di esecuzione, consulta Proteggere la funzione Cloud Functions.

Node.js

Runtime Generazione Ambiente ID runtime Immagine runtime Ritiro Ritiro
Node.js 20 1ª generazione, 2ª generazione. Ubuntu 22.04 nodejs20 gcr.io/gae-runtimes/buildpacks/nodejs20/run 2026-04-30 2026-10-30
Node.js 18 1ª generazione, 2ª generazione. Ubuntu 22.04 nodejs18 gcr.io/gae-runtimes/buildpacks/nodejs18/run 2025-04-30 2025-10-30
Node.js 16 1ª generazione, 2ª generazione. Ubuntu 18.04 nodejs16 gcr.io/gae-runtimes/buildpacks/nodejs16/run 2024-01-30 2025-01-30
Node.js 14 1ª generazione, 2ª generazione. Ubuntu 18.04 nodejs14 gcr.io/gae-runtimes/buildpacks/nodejs14/run 2024-01-30 2025-01-30
Node.js 12 1ª generazione, 2ª generazione. Ubuntu 18.04 nodejs12 gcr.io/gae-runtimes/buildpacks/nodejs12s/run 2024-01-30 2025-01-30
Node.js 10 1ª generazione, 2ª generazione. Ubuntu 18.04 nodejs10 gcr.io/gae-runtimes/buildpacks/nodejs10/run 2024-01-30 2025-01-30
Node.js 8 1ª generazione, 2ª generazione. Ubuntu 18.04 nodejs8 gcr.io/gae-runtimes/buildpacks/nodejs8/run 2020-06-05 Febbraio 2021
Node.js 6 1ª generazione, 2ª generazione. Ubuntu 18.04 nodejs6 gcr.io/gae-runtimes/buildpacks/nodejs6/run 2019-04-17 Agosto 2020

Python

Runtime Generazione Ambiente ID runtime Immagine runtime Ritiro Ritiro
Python 3.12 1ª generazione, 2ª generazione. Ubuntu 22.04 python312 gcr.io/gae-runtimes/buildpacks/python312/run 2028-10-02 2029-04-02
Python 3.11 1ª generazione, 2ª generazione. Ubuntu 22.04 python311 gcr.io/gae-runtimes/buildpacks/python311/run 2027-10-24 2028-04-24
Python 3.10 1ª generazione, 2ª generazione. Ubuntu 22.04 python310 gcr.io/gae-runtimes/buildpacks/python310/run 2026-10-04 2027-04-04
Python 3.9 1ª generazione, 2ª generazione. Ubuntu 18.04 python39 gcr.io/gae-runtimes/buildpacks/python39/run 2025-10-05 2026-04-05
Python 3.8 1ª generazione, 2ª generazione. Ubuntu 18.04 python38 gcr.io/gae-runtimes/buildpacks/python38/run 2024-10-14 2025-10-14
Python 3.7 1ª generazione Ubuntu 18.04 python37 gcr.io/gae-runtimes/buildpacks/python37/run 2024-01-30 2025-01-30

Go

Runtime Generazione Ambiente ID runtime Immagine runtime Ritiro Ritiro
Vai 1.22 2ª generazione Ubuntu 22.04 go122 gcr.io/gae-runtimes/buildpacks/go122/run
Vai 1.21 1ª generazione, 2ª generazione. Ubuntu 22.04 go121 gcr.io/gae-runtimes/buildpacks/go121/run
Vai a 1.20 1ª generazione, 2ª generazione. Ubuntu 22.04 go120 gcr.io/gae-runtimes/buildpacks/go120/run 2024-05-01 2025-05-01
Vai 1.19 1ª generazione, 2ª generazione. Ubuntu 22.04 go119 gcr.io/gae-runtimes/buildpacks/go119/run 2024-04-30 2025-01-30
Vai 1.18 1ª generazione, 2ª generazione. Ubuntu 22.04 go118 gcr.io/gae-runtimes/buildpacks/go118/run 2024-01-30 2025-01-30
Go 1.16 1ª generazione, 2ª generazione. Ubuntu 18.04 go116 gcr.io/gae-runtimes/buildpacks/go116/run 2024-01-30 2025-01-30
Go 1.13 1ª generazione, 2ª generazione. Ubuntu 18.04 go113 gcr.io/gae-runtimes/buildpacks/go113/run 2024-01-30 2025-01-30
Vai 1.12 1ª generazione, 2ª generazione. Ubuntu 18.04 go112 gcr.io/gae-runtimes/buildpacks/go112/run 2024-01-30 2025-01-30
Go 1.11 1ª generazione, 2ª generazione. Ubuntu 18.04 go111 gcr.io/gae-runtimes/buildpacks/go111/run 2020-08-05 Febbraio 2021

Java

Runtime Generazione Ambiente ID runtime Immagine runtime Ritiro Ritiro
Java 21 2ª generazione Ubuntu 22.04 java21 gcr.io/gae-runtimes/buildpacks/java21/run Ottobre 2031
Java 17 1ª generazione, 2ª generazione. Ubuntu 22.04 java17 gcr.io/gae-runtimes/buildpacks/java17/run Ottobre 2027
Java 11 1ª generazione, 2ª generazione. Ubuntu 18.04 java11 gcr.io/gae-runtimes/buildpacks/java11/run Ottobre 2024

Ruby

Runtime Generazione Ambiente ID runtime Immagine runtime Ritiro Ritiro
Ruby 3.2 1ª generazione, 2ª generazione. Ubuntu 22.04 ruby32 gcr.io/gae-runtimes/buildpacks/ruby32/run 2026-03-31 2026-09-30
Ruby 3.0 1ª generazione, 2ª generazione. Ubuntu 18.04 ruby30 gcr.io/gae-runtimes/buildpacks/ruby30/run 2024-03-31 2025-03-31
Ruby 2.7 1ª generazione, 2ª generazione. Ubuntu 18.04 ruby27 gcr.io/gae-runtimes/buildpacks/ruby27/run 2024-01-30 2025-01-30
Ruby 2.6 1ª generazione, 2ª generazione. Ubuntu 18.04 ruby26 gcr.io/gae-runtimes/buildpacks/ruby26/run 2024-01-30 2025-01-30

PHP

Runtime Ambiente Generazione ID runtime Immagine runtime Ritiro Ritiro
PHP 8.3 2ª generazione Ubuntu 22.04 php83 gcr.io/gae-runtimes/buildpacks/php83/run 2026-11-23 2027-05-23
PHP 8.2 1ª generazione, 2ª generazione. Ubuntu 22.04 php82 gcr.io/gae-runtimes/buildpacks/php82/run 2025-12-08 2026-06-08
PHP 8.1 1ª generazione, 2ª generazione. Ubuntu 18.04 php81 gcr.io/gae-runtimes/buildpacks/php81/run 2024-11-25 2025-11-25
PHP 7.4 1ª generazione, 2ª generazione. Ubuntu 18.04 php74 gcr.io/gae-runtimes/buildpacks/php74/run 2024-01-30 2025-01-30

.NET Core

Runtime Generazione Ambiente ID runtime Immagine runtime Ritiro Ritiro
.NET Core 8 2ª generazione Ubuntu 22.04 dotnet8 gcr.io/gae-runtimes/buildpacks/dotnet8/run
.NET Core 6 1ª generazione, 2ª generazione. Ubuntu 22.04 dotnet6 gcr.io/gae-runtimes/buildpacks/dotnet6/run 2024-11-12 2025-11-12
.NET Core 3 1ª generazione, 2ª generazione. Ubuntu 18.04 dotnet3 gcr.io/gae-runtimes/buildpacks/dotnet3/run 2024-01-30 2025-01-30

Comportamento della scalabilità automatica

Cloud Functions implementa il paradigma serverless, in cui viene eseguito il codice senza doversi preoccupare dell'infrastruttura sottostante, ad esempio server o macchine virtuali. Una volta eseguito il deployment, le funzioni vengono gestite e scalate automaticamente.

Cloud Functions gestisce le richieste in entrata assegnandole alle istanze della funzione. A seconda del volume di richieste e del numero di istanze di funzione esistenti, Cloud Functions può assegnare una richiesta a un'istanza esistente o crearne una nuova.

Nei casi in cui il volume delle richieste in entrata supera il numero di istanze esistenti, Cloud Functions può avviare più nuove istanze per gestire le richieste. Questo comportamento di scalabilità automatica consente a Cloud Functions di gestire molte richieste in parallelo, ciascuna utilizzando un'istanza diversa della funzione.

In alcuni casi, la scalabilità illimitata potrebbe essere indesiderabile. Per risolvere questo problema, Cloud Functions consente di configurare un numero massimo di istanze che possono coesistere in un dato momento per una determinata funzione.

Condizione stateless

Per abilitare la gestione e la scalabilità automatiche delle funzioni, le funzioni devono essere stateless: una chiamata a una funzione non deve fare affidamento sullo stato in memoria impostato da una chiamata precedente. Le chiamate potrebbero essere gestite da istanze di funzione diverse, che non condividono variabili globali, memoria, file system o altri stati.

Se devi condividere lo stato tra le chiamate alla funzione, la funzione deve utilizzare un servizio come Memorystore, Datastore, Firestore o Cloud Storage per rendere i dati persistenti. Consulta i database Google Cloud e i prodotti di archiviazione di Google Cloud per ulteriori informazioni sulle opzioni di database e archiviazione fornite da Google Cloud.

Contemporaneità

Cloud Functions (2nd gen)

Cloud Functions (2nd gen) supporta la gestione di più richieste in parallelo su un'istanza di funzione singola. Ciò può essere utile per impedire gli avvii a freddo poiché un'istanza già riscaldata può elaborare più richieste contemporaneamente, riducendo così la latenza complessiva. Per maggiori dettagli, consulta Contemporaneità.

Cloud Functions (1ª generazione.)

In Cloud Functions (1ª generazione), ogni istanza di una funzione gestisce una sola richiesta in parallelo alla volta. Ciò significa che, mentre il codice elabora una richiesta, non è possibile che una seconda richiesta venga instradata alla stessa istanza. Di conseguenza, la richiesta originale può utilizzare l'intera quantità di risorse (memoria e CPU) allocate.

Poiché le richieste in parallelo in Cloud Functions (1ª generazione.) vengono elaborate da istanze di funzione diverse, non condividono variabili o memoria locale. Per ulteriori informazioni, consulta Statelessness e Durata dell'istanza della funzione.

Avvii a freddo

Una nuova istanza di funzione viene avviata in due casi:

  • Quando esegui il deployment della funzione.

  • Quando viene creata automaticamente una nuova istanza di funzione per fare lo scale up al carico, o occasionalmente per sostituire un'istanza esistente.

L'avvio di una nuova istanza di funzione comporta il caricamento del runtime e del codice. Le richieste che includono l'avvio di istanze di funzione, denominate avvii a freddo, possono essere più lente rispetto alle richieste instradate a istanze di funzione esistenti. Tuttavia, se la funzione riceve un carico costante, il numero di avvii a freddo è in genere trascurabile, a meno che la funzione non si arresti spesso in modo anomalo e richieda il riavvio dell'ambiente della funzione.

Se il codice della funzione genera un'eccezione non rilevata o arresta il processo attuale, l'istanza della funzione potrebbe essere riavviata. Ciò può portare a un numero maggiore di avvii a freddo, con una conseguente maggiore latenza, quindi consigliamo di individuare le eccezioni e, in caso contrario, di evitare la fine del processo attuale. Per una discussione su come gestire e segnalare gli errori in Cloud Functions, consulta la sezione Errori dei report.

Se la tua funzione è sensibile alla latenza, valuta la possibilità di impostare un numero minimo di istanze per evitare gli avvii a freddo.

Durata dell'istanza della funzione

Le istanze delle funzioni sono in genere resilienti e riutilizzate dalle chiamate di funzione successive, a meno che non venga fatto lo scale down del numero di istanze a causa della mancanza di traffico in corso o che la funzione non si arresti in modo anomalo. Ciò significa che, al termine dell'esecuzione di una funzione, la chiamata di un'altra funzione può essere gestita dalla stessa istanza di funzione.

Confronto tra ambito delle funzioni e ambito globale

Una chiamata a funzione singola comporta l'esecuzione del solo corpo della funzione dichiarata come punto di ingresso. L'ambito globale del codice sorgente della funzione viene eseguito solo con gli avvii a freddo e non nelle istanze già inizializzate.

Node.js

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

// TODO(developer): Define your own computations
const {lightComputation, heavyComputation} = require('./computations');

// Global (instance-wide) scope
// This computation runs once (at instance cold-start)
const instanceVar = heavyComputation();

/**
 * HTTP function that declares a variable.
 *
 * @param {Object} req request context.
 * @param {Object} res response context.
 */
functions.http('scopeDemo', (req, res) => {
  // Per-function scope
  // This computation runs every time this function is called
  const functionVar = lightComputation();

  res.send(`Per instance: ${instanceVar}, per function: ${functionVar}`);
});

Python

import time

import functions_framework

# Placeholder
def heavy_computation():
    return time.time()

# Placeholder
def light_computation():
    return time.time()

# Global (instance-wide) scope
# This computation runs at instance cold-start
instance_var = heavy_computation()

@functions_framework.http
def scope_demo(request):
    """
    HTTP Cloud Function that declares a variable.
    Args:
        request (flask.Request): The request object.
        <http://flask.pocoo.org/docs/1.0/api/#flask.Request>
    Returns:
        The response text, or any set of values that can be turned into a
        Response object using `make_response`
        <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>.
    """

    # Per-function scope
    # This computation runs every time this function is called
    function_var = light_computation()
    return f"Instance: {instance_var}; function: {function_var}"

Go


// h is in the global (instance-wide) scope.
var h string

// init runs during package initialization. So, this will only run during an
// an instance's cold start.
func init() {
	h = heavyComputation()
	functions.HTTP("ScopeDemo", ScopeDemo)
}

// ScopeDemo is an example of using globally and locally
// scoped variables in a function.
func ScopeDemo(w http.ResponseWriter, r *http.Request) {
	l := lightComputation()
	fmt.Fprintf(w, "Global: %q, Local: %q", h, l)
}

Java


import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

public class Scopes implements HttpFunction {
  // Global (instance-wide) scope
  // This computation runs at instance cold-start.
  // Warning: Class variables used in functions code must be thread-safe.
  private static final int INSTANCE_VAR = heavyComputation();

  @Override
  public void service(HttpRequest request, HttpResponse response)
      throws IOException {
    // Per-function scope
    // This computation runs every time this function is called
    int functionVar = lightComputation();

    var writer = new PrintWriter(response.getWriter());
    writer.printf("Instance: %s; function: %s", INSTANCE_VAR, functionVar);
  }

  private static int lightComputation() {
    int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    return Arrays.stream(numbers).sum();
  }

  private static int heavyComputation() {
    int[] numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    return Arrays.stream(numbers).reduce((t, x) -> t * x).getAsInt();
  }
}

Ruby

# Global (instance-wide) scope.
# This block runs on cold start, before any function is invoked.
#
# Note: It is usually best to run global initialization in an on_startup block
# instead at the top level of the Ruby file. This is because top-level code
# could be executed to verify the function during deployment, whereas an
# on_startup block is run only when an actual function instance is starting up.
FunctionsFramework.on_startup do
  instance_data = perform_heavy_computation

  # To pass data into function invocations, the best practice is to set a
  # key-value pair using the Ruby Function Framework's built-in "set_global"
  # method. Functions can call the "global" method to retrieve the data by key.
  # (You can also use Ruby global variables or "toplevel" local variables, but
  # they can make it difficult to isolate global data for testing.)
  set_global :my_instance_data, instance_data
end

FunctionsFramework.http "tips_scopes" do |_request|
  # Per-function scope.
  # This method is called every time this function is called.
  invocation_data = perform_light_computation

  # Retrieve the data computed by the on_startup block.
  instance_data = global :my_instance_data

  "instance: #{instance_data}; function: #{invocation_data}"
end

Puoi utilizzare le variabili globali per l'ottimizzazione delle prestazioni, ma non devi fare affidamento sullo stato impostato nell'ambito globale da chiamate di funzione precedenti. Per ulteriori informazioni, consulta la sezione Statelessness.

Si può presumere che per ogni istanza di funzione, l'ambito globale sia stato eseguito esattamente una volta prima di richiamare il codice della funzione. Tuttavia, non devi dipendere dal numero totale o dalle tempistiche delle esecuzioni in ambito globale, poiché potrebbero variare a seconda dell'attività di scalabilità automatica.

Sequenza temporale di esecuzione della funzione

Una funzione ha accesso alle risorse allocate (memoria e CPU) solo per la durata dell'esecuzione della funzione. L'esecuzione del codice al di fuori del periodo di esecuzione non è garantita e può essere interrotta in qualsiasi momento. Pertanto, devi sempre segnalare correttamente la fine dell'esecuzione della funzione ed evitare di eseguire qualsiasi codice al di fuori della funzione. Per indicazioni, consulta Funzioni HTTP, Funzioni in background e CloudEvent Functions.

L'esecuzione della funzione è soggetta anche alla durata del timeout della funzione. Per ulteriori informazioni, consulta Timeout funzione.

Tieni conto delle tempistiche di esecuzione quando inizializzi l'applicazione. Le attività in background non devono essere create in ambito globale durante l'inizializzazione, poiché verrebbero eseguite al di fuori della durata di una richiesta.

Garanzie di esecuzione

In genere, le funzioni vengono richiamate una volta per ogni evento in entrata. Tuttavia, Cloud Functions non garantisce una singola chiamata in tutti i casi a causa delle differenze negli scenari di errore.

Il numero massimo o minimo di volte in cui è possibile richiamare la funzione per un singolo evento dipende dal tipo di funzione:

  • Le funzioni HTTP vengono richiamate più una volta. Questo è dovuto alla natura sincrona delle chiamate HTTP e ciò significa che qualsiasi errore che si verifica durante la chiamata della funzione verrà restituito senza ulteriori tentativi. Il chiamante di una funzione HTTP dovrebbe gestire gli errori e riprovare, se necessario.

  • Le funzioni basate su eventi vengono richiamate almeno una volta. Ciò è dovuto alla natura asincrona degli eventi, in cui non esiste un chiamante che attende la risposta. In rare circostanze, il sistema potrebbe richiamare una funzione basata su eventi più di una volta per garantire la distribuzione dell'evento. Se la chiamata di una funzione basata su eventi non va a buon fine e viene restituito un errore, la funzione non verrà richiamata di nuovo a meno che non siano abilitati nuovi tentativi in caso di errore per quella funzione.

Per assicurarti che la funzione si comporti correttamente in caso di nuovi tentativi di esecuzione, devi renderla idempotente implementandola in modo che vengano generati i risultati (e gli effetti collaterali) desiderati, anche se un evento viene pubblicato più volte. Nel caso delle funzioni HTTP, ciò significa anche restituire il valore desiderato anche se il chiamante tenta di nuovo di richiamare l'endpoint della funzione HTTP. Per ulteriori informazioni su come rendere la funzione idempotente, consulta Ripetere le funzioni basate su eventi.

Memoria e file system

Ogni funzione ha una certa quantità di memoria allocata per il suo utilizzo. Puoi configurare la quantità di memoria al momento del deployment. Per ulteriori informazioni, consulta Limiti di memoria.

L'ambiente di esecuzione della funzione include un file system in memoria che contiene i file di origine e le directory di cui è stato eseguito il deployment con la funzione (vedi Struttura del codice sorgente). La directory contenente i file di origine è di sola lettura, ma il resto del file system è scrivibile (ad eccezione dei file utilizzati dal sistema operativo). L'utilizzo del file system viene conteggiato ai fini dell'utilizzo della memoria da parte di una funzione.

La funzione può interagire con il file system utilizzando metodi standard in ciascun linguaggio di programmazione.

Rete

La funzione può accedere alla rete internet pubblica utilizzando metodi standard in ogni linguaggio di programmazione, tramite le librerie integrate offerte dal runtime o le librerie di terze parti che includi come dipendenze.

Prova a riutilizzare le connessioni di rete nelle chiamate alle funzioni, come descritto in Ottimizzazione della rete. Tuttavia, tieni presente che una connessione che rimane inutilizzata per 10 minuti potrebbe essere chiusa dal sistema e ulteriori tentativi di utilizzare una connessione chiusa causeranno un errore di "reimpostazione della connessione". Il codice dovrebbe utilizzare una libreria che gestisca bene le connessioni chiuse oppure gestirle in modo esplicito se utilizzi costrutti di networking di basso livello.

Isolamento delle funzioni

Ogni funzione di cui è stato eseguito il deployment è isolata da tutte le altre funzioni, anche quelle di cui è stato eseguito il deployment dallo stesso file di origine. In particolare, non condividono memoria, variabili globali, file system o altri stati.

Per condividere i dati tra le funzioni di cui è stato eseguito il deployment, puoi utilizzare servizi come Memorystore, Datastore, Firestore o Cloud Storage. In alternativa, puoi richiamare una funzione da un'altra utilizzando i trigger appropriati e trasmettendo i dati necessari. Ad esempio, effettua una richiesta HTTP all'endpoint di una funzione HTTP o pubblica un messaggio in un argomento Pub/Sub per attivare una funzione Pub/Sub.