Questo documento descrive come attivare i tentativi di nuovo per le funzioni CloudEvents, note anche come funzioni basate su eventi. I tentativi automatici non sono disponibili per le funzioni HTTP.
Perché le funzioni basate su eventi non riescono a completare l'esecuzione
In rari casi, una funzione potrebbe uscire prematuramente a causa di un errore interno e, per impostazione predefinita, la funzione potrebbe o meno essere ripetuta automaticamente.
Più in generale, una funzione basata su eventi potrebbe non essere completata correttamente a causa di errori generati nel codice della funzione stessa. Ecco alcuni motivi per cui questo potrebbe accadere:
- La funzione contiene un bug e il runtime genera un'eccezione.
- La funzione non riesce a raggiungere un endpoint del servizio o il timeout si verifica durante il tentativo di farlo.
- La funzione genera intenzionalmente un'eccezione (ad esempio quando un parametro non supera la convalida).
- Una funzione Node.js restituisce una promessa rifiutata o passa un valore diverso da
null
a un callback.
In uno dei casi precedenti, la funzione interromperà l'esecuzione e restituirà un errore. Gli attivatori di eventi che producono i messaggi hanno criteri di ripetizione che puoi personalizzare per soddisfare le esigenze della tua funzione.
Semantica della ripetizione
Le funzioni Cloud Run forniscono l'esecuzione almeno una volta di una funzione basata su eventi per ogni evento emesso da un'origine evento. Il modo in cui configuri i tentativi dipende dalla modalità di creazione della funzione:
- Le funzioni create nella console Google Cloud o con l'API di amministrazione Cloud Run richiedono di creare e gestire separatamente gli attivatori di eventi. Gli attivatori hanno comportamenti di ripetizione predefiniti che puoi personalizzare in base alle esigenze della tua funzione.
- Le funzioni create con l'API Cloud Functions v2 creeranno implicitamente gli attivatori di eventi necessari, ad esempio gli argomenti Pub/Sub o gli attivatori Eventarc. Per impostazione predefinita, i tentativi di nuovo invio sono disattivati per questi trigger e possono essere riattivati utilizzando l'API Cloud Functions v2.
Funzioni basate su eventi create con Cloud Run
Le funzioni create nella console Google Cloud o con l'API Cloud Run Admin require di creare e gestire separatamente gli attivatori di eventi. Ti consigliamo vivamente di esaminare il comportamento predefinito di ciascun tipo di attivatore:
- Il criterio di ripetizione di Eventarc ha un valore predefinito per la conservazione dei messaggi di 24 ore con un ritardo di backoff esponenziale. Consulta la documentazione di Eventarc sugli eventi di ripetizione.
- Per impostazione predefinita, Pub/Sub utilizza il criterio di ripubblicazione immediata per tutte le sottoscrizioni. Consulta la documentazione di Pub/Sub su gestione degli errori relativi ai messaggi e su richieste di ripetizione.
Funzioni basate su eventi create con l'API Cloud Functions v2
Funzioni create utilizzando l'API Cloud Functions v2, ad esempio utilizzando l'interfaccia a riga di comando gcloud di Cloud Functions, l'API REST o Terraform, che creeranno e gestiranno gli attivatori di eventi per tuo conto. Per impostazione predefinita, se l'invocazione di una funzione termina con un errore, la funzione non viene invocata di nuovo e l'evento viene ignorato. Quando attivi i tentativi di nuovo su una funzione basata su eventi, le funzioni Cloud Run tentano di nuovo un'invocazione di funzione non riuscita finché non viene completata correttamente o non scade il periodo di tempo per i tentativi di nuovo.
Quando i tentativi di nuovo non sono abilitati per una funzione, che è l'impostazione predefinita, la funzione
segnala sempre che è stata eseguita correttamente e nei log potrebbero essere visualizzati i codici di risposta 200 OK
. Ciò si verifica anche se la funzione ha rilevato un errore. Per chiarire quando la funzione rileva un errore, assicurati di segnalare gli errori in modo appropriato.
Attivare o disattivare i tentativi di nuovo invio
Per attivare o disattivare i tentativi di nuovo invio, puoi utilizzare lo strumento a riga di comando gcloud
o la console Google Cloud . Per impostazione predefinita, i tentativi di nuovo invio sono disattivati.
Configurare i tentativi di nuovo invio dallo strumento a riga di comando gcloud
Per abilitare i tentativi di nuovo utilizzando lo strumento a riga di comando gcloud
, includi il flag --retry
durante il deployment della funzione:
gcloud functions deploy FUNCTION_NAME --retry FLAGS...
Per disattivare i nuovi tentativi, esegui nuovamente il deployment della funzione senza il flag --retry
:
gcloud functions deploy FUNCTION_NAME FLAGS...
Configurare i tentativi di nuovo invio dalla console
Se stai creando una nuova funzione:
- Nella schermata Crea funzione, in Attivati, scegli il tipo di evento da utilizzare come attivatore per la funzione.
- Seleziona la casella di controllo Riprova in caso di errore per attivare i tentativi di nuovo invio.
Se stai aggiornando una funzione esistente:
- Nella pagina Panoramica delle funzioni Cloud Run, fai clic sul nome della funzione che stai aggiornando per aprire la schermata Dettagli funzione, quindi scegli Modifica dalla barra dei menu per visualizzare il riquadro Attivazione.
- Seleziona o deseleziona la casella di controllo Riprova in caso di errore per attivare o disattivare i tentativi di nuovo accesso.
Finestra Riprova
Questa finestra di ripetizione dell'operazione scade dopo 24 ore. Cloud Run functions riprova le funzioni basate su eventi appena create utilizzando una strategia di backoff esponenziale, con un backoff crescente compreso tra 10 e 600 secondi.Best practice
Questa sezione descrive le best practice per l'utilizzo dei tentativi di nuovo invio.
Utilizzare la ripetizione per gestire gli errori temporanei
Poiché la funzione viene tentata di nuovo continuamente fino a un'esecuzione riuscita, gli errori permanenti come i bug devono essere eliminati dal codice tramite i test prima di attivare i tentativi di nuovo. I tentativi sono ideali per gestire errori intermittenti o temporanei con un'alta probabilità di risoluzione al successivo tentativo, ad esempio un endpoint di servizio inaffidabile o un timeout.
Imposta una condizione di fine per evitare cicli di tentativi infiniti
È buona prassi proteggere la funzione da un ciclo continuo quando si utilizzano i tentativi. Puoi farlo includendo una condizione di fine ben definita, prima dell'inizio dell'elaborazione della funzione. Tieni presente che questa tecnica funziona solo se la funzione si avvia correttamente ed è in grado di valutare la condizione di fine.
Un approccio semplice ma efficace è eliminare gli eventi con timestamp precedenti a un determinato momento. In questo modo si evitano esecuzioni eccessive quando gli errori sono persistenti o durano più a lungo del previsto.
Ad esempio, questo snippet di codice ignora tutti gli eventi precedenti a 10 secondi:
Node.js
Python
Vai
Java
C#
Ruby
PHP
Distinguere tra funzioni che possono essere riprovate ed errori irreversibili
Se per la funzione sono abilitati i nuovi tentativi, qualsiasi errore non gestito attiverà un nuovo tentativo. Assicurati che il codice catturi eventuali errori che non devono comportare un nuovo tentativo.
Node.js
Python
Vai
Java
C#
Ruby
PHP
Rendere idempotenti le funzioni basate su eventi ripetibili
Le funzioni basate su eventi per le quali è possibile riprovare devono essere idempotenti. Ecco alcune linee guida generali per rendere idempotente una funzione di questo tipo:
- Molte API esterne (come Stripe) ti consentono di fornire una chiave di idempotenza come parametro. Se utilizzi un'API di questo tipo, devi utilizzare l'ID evento come chiave di iride.
- L'idempotenza funziona bene con la consegna "almeno una volta", perché consente di eseguire nuovamente il tentativo in sicurezza. Pertanto, una best practice generale per scrivere codice affidabile è combinare l'idempotenza con i tentativi di nuovo.
- Assicurati che il codice sia internamente idempotente. Ad esempio:
- Assicurati che le mutazioni possano verificarsi più di una volta senza modificare il risultato.
- Esegui query sullo stato del database in una transazione prima di modificarlo.
- Assicurati che tutti gli effetti collaterali siano idempotenti.
- Imposta un controllo transazionale esterno alla funzione, indipendente dal codice. Ad esempio, mantieni lo stato da qualche parte registrando che un determinato ID evento è stato già elaborato.
- Gestisci le chiamate di funzioni duplicate out-of-band. Ad esempio, puoi avere un processo di pulizia distinto che elimina i dati dopo le chiamate di funzioni duplicate.
Configura il criterio di ripetizione
A seconda delle esigenze della tua funzione Cloud Run, ti consigliamo di configurare direttamente il criterio di ripetizione. In questo modo, puoi configurare qualsiasi combinazione di quanto segue:
- Riduci il periodo di attesa per il nuovo tentativo da 7 giorni a un minimo di 10 minuti.
- Modifica il tempo di attesa minimo e massimo per la strategia di ripetizione con tempo di attesa esponenziale.
- Modifica la strategia di ripetizione in modo da riprovare immediatamente.
- Configura un argomento messaggi non recapitabili.
- Imposta un numero massimo e minimo di tentativi di invio.
Per configurare il criterio di ripetizione:
- Scrivi una funzione HTTP.
- Utilizza l'API Pub/Sub per creare un abbonamento Pub/Sub, specificando l'URL della funzione come target.
Consulta la documentazione di Pub/Sub sulla gestione degli errori per ulteriori informazioni sulla configurazione diretta di Pub/Sub.
Passaggi successivi
- Eseguire il deployment di funzioni Cloud Run
- Chiamare le funzioni di trigger Pub/Sub
- Chiamare le funzioni di attivazione di Cloud Storage
- Tutorial sulle funzioni Cloud Run con Pub/Sub
- Tutorial sulle funzioni Cloud Run con Cloud Storage