View a markdown version of this page

Comprendere il ciclo di vita dell’ambiente di esecuzione Lambda - AWS Lambda

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Comprendere il ciclo di vita dell’ambiente di esecuzione Lambda

Gli ambienti di esecuzione Lambda supportano sia le funzioni standard (fino a 15 minuti) che le funzioni durature (fino a un anno). Sebbene entrambi condividano lo stesso ciclo di vita di base, Durable Functions aggiunge funzionalità di gestione dello stato per flussi di lavoro di lunga durata.

Lambda richiama la funzione in un ambiente di esecuzione, che fornisce un ambiente di runtime sicuro e isolato. L'ambiente di esecuzione gestisce le risorse necessarie per eseguire la funzione. L'ambiente di esecuzione fornisce inoltre il supporto del ciclo di vita per il runtime della funzione e per tutte le estensioni esterne associate alla funzione.

Per Durable Functions, l'ambiente di esecuzione include componenti aggiuntivi per:

  • Persistenza dello stato tra i passaggi

  • Gestione dei checkpoint

  • Attendi il coordinamento dello stato

  • Monitoraggio dei progressi

Ambiente di esecuzione delle istanze gestite Lambda

Se utilizzi Lambda Managed Instances, l'ambiente di esecuzione presenta differenze importanti rispetto alle funzioni Lambda (predefinite). Le istanze gestite supportano invocazioni simultanee, utilizzano un modello di ciclo di vita diverso e vengono eseguite su un'infrastruttura di proprietà del cliente. Per informazioni dettagliate sull'ambiente di esecuzione delle istanze gestite, consulta. Comprendere l'ambiente di esecuzione delle istanze gestite Lambda

Il runtime della funzione comunica con Lambda e usa l'API Runtime. Le estensioni comunicano con Lambda utilizzando le API estensioni. Le estensioni possono anche ricevere messaggi di log e altra telemetria dalla funzione tramite l'API di telemetria.

Diagramma di architettura dell'ambiente di esecuzione.

Quando si crea la funzione Lambda, si specificano le informazioni di configurazione, ad esempio la quantità di memoria disponibile e il tempo massimo di esecuzione consentito per la funzione. Lambda utilizza queste informazioni per impostare l'ambiente di esecuzione.

Il runtime della funzione e ogni estensione esterna sono processi eseguiti all'interno dell'ambiente di esecuzione. Le autorizzazioni, le risorse, le credenziali e le variabili di ambiente sono condivise tra la funzione e le estensioni.

Ciclo di vita dell'ambiente di esecuzione Lambda

Fasi del ciclo di vita Lambda: Init, Invoke, Shutdown.

Ogni fase inizia con un evento che Lambda invia al runtime e a tutte le estensioni registrate. Il runtime e ogni estensione indicano il completamento inviando una richiesta API Next. Lambda congela l'ambiente di esecuzione quando il runtime e ogni estensione sono stati completati e non ci sono eventi in sospeso.

Le fasi del ciclo di vita di Durable Functions includono:

  • Init: inizializzazione standard più configurazione dello stato duraturo

  • Invoke: può includere esecuzioni di più passaggi con checkpoint automatico

  • Attendi: la funzione può sospendere l'esecuzione senza consumare risorse

  • Riprendi: la funzione si riavvia dall'ultimo checkpoint

  • Arresto: pulizia dello stato e delle risorse durevoli

Fase di init

Nella fase Init, Lambda esegue tre incarichi:

  • Avvia tutte le estensioni (Extension init)

  • Esegue il bootstrap del runtime (Runtime init)

  • Esegue il codice statico della funzione (Function init)

  • Esegui qualsiasi hook di runtime prima del checkpoint (solo Lambda) SnapStart

La fase Init termina quando il runtime e tutte le estensioni segnalano che sono pronti inviando una richiesta Next API. La fase Init è limitata a 10 secondi. Se tutte e tre le attività non vengono completate entro 10 secondi, Lambda ritenta la fase Init al momento della prima chiamata di funzione con timeout della funzione configurata.

Quando SnapStart è attivato, la fase Init si verifica quando si pubblica una versione della funzione. Lambda salva uno snapshot della memoria e dello stato del disco dell'ambiente di esecuzione inizializzato, mantiene lo snapshot crittografato e lo memorizza nella cache per l'accesso a bassa latenza. Se disponi di un hook di runtime prima del checkpoint, il codice viene eseguito alla fine della fase Init.

Nota

Il timeout di 10 secondi non si applica alle funzioni che utilizzano la concorrenza predisposta o le istanze gestite Lambda. SnapStart Per le funzioni di concorrenza con provisioning e Managed Instances SnapStart, il codice di inizializzazione può essere eseguito per un massimo di 15 minuti. Il limite di tempo è 130 secondi o il timeout della funzione configurato (massimo 900 secondi), a seconda di quale dei due valori sia più elevato.

Quando utilizzi la simultaneità fornita, Lambda inizializza l'ambiente di esecuzione quando configuri le impostazioni del PC per una funzione. Lambda, inoltre, garantisce che gli ambienti di esecuzione inizializzati siano sempre disponibili prima delle invocazioni. Potresti notare delle lacune tra le fasi di richiamo e inizializzazione della funzione. A seconda del runtime e della configurazione della memoria della funzione, è inoltre possibile che si verifichi una latenza variabile alla prima chiamata in un ambiente di esecuzione inizializzato.

Per le funzioni che utilizzano la concorrenza su richiesta, Lambda potrebbe occasionalmente inizializzare gli ambienti di esecuzione prima delle richieste di richiamo. Quando ciò accade, potresti anche osservare un intervallo di tempo tra le fasi di inizializzazione e invocazione della funzione. È preferibile non acquisire dipendenza da questo comportamento.

Errori durante la fase di inizializzazione

Se una funzione si arresta in modo anomalo o si verifica un timeout durante la fase Init, Lambda emette informazioni sull'errore nel log INIT_REPORT.

Esempio— Log INIT_REPORT per il timeout
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: timeout
Esempio— Log INIT_REPORT per gli errori di estensione
INIT_REPORT Init Duration: 1236.04 ms Phase: init Status: error Error Type: Extension.Crash

Se la Init fase ha esito positivo, Lambda non emette il INIT_REPORT log a meno che non sia abilitata la concorrenza predisposta SnapStart. Configurazione della simultaneità fornita per una funzione SnapStart e le funzioni di concorrenza predisposte emettono sempre. INIT_REPORT Per ulteriori informazioni, consulta Monitoraggio per Lambda SnapStart.

Fase di ripristino (solo Lambda) SnapStart

Quando si richiama per la prima volta una SnapStart funzione e man mano che la funzione aumenta, Lambda riprende nuovi ambienti di esecuzione dallo snapshot persistente invece di inizializzare la funzione da zero. Se disponi di un hook di runtime dopo il ripristino, il codice viene eseguito alla fine della fase Restore. Ti sarà addebitata la durata degli hook di runtime dopo il ripristino. Il runtime deve essere caricato e gli hook di runtime dopo il ripristino devono essere completati entro il limite di timeout (10 secondi). Altrimenti, otterrai un. SnapStartTimeoutException Al termine della fase Restore, Lambda chiama il gestore della funzione (Invoca fase).

Errori durante la fase di ripristino

Se la fase Restore fallisce, Lambda emette informazioni sull'errore nel log RESTORE_REPORT.

Esempio— Log RESTORE_REPORT per il timeout
RESTORE_REPORT Restore Duration: 1236.04 ms Status: timeout
Esempio— Log RESTORE_REPORT per gli errori dell'hook di runtime
RESTORE_REPORT Restore Duration: 1236.04 ms Status: error Error Type: Runtime.ExitError

Per ulteriori informazioni sul log RESTORE_REPORT, consulta la pagina Monitoraggio per Lambda SnapStart.

Invoca fase

Quando una funzione Lambda viene richiamata in risposta a una richiesta API Next, Lambda invia un evento Invoke al runtime e a ogni estensione.

L'impostazione di timeout della funzione limita la durata dell'intera fase Invoke. Ad esempio, se si imposta il timeout della funzione come 360 secondi, la funzione e tutte le estensioni devono essere completate entro 360 secondi. Si noti che non esiste una fase post-richiamo indipendente. La durata è la somma di tutto il tempo di chiamata (runtime + estensioni) e non viene calcolata fino a quando la funzione e tutte le estensioni non hanno terminato l'esecuzione.

La fase di richiamo termina dopo il runtime e tutte le estensioni segnalano che vengono eseguite inviando una richiesta Next API.

Errori durante la fase di richiamo

Se la funzione Lambda si arresta in modo anomalo o si verifica un timeout durante la fase Invoke, Lambda reimposta l'ambiente di esecuzione. Il diagramma seguente mostra il comportamento dell'ambiente di esecuzione Lambda in caso di errore di invocazione:

Esempio di ambiente di esecuzione: Init, Invoke, Invoke with Error, Invoke, Shutdown.

Nel diagramma precedente:

  • La prima è la fase INIT e viene eseguita senza errori.

  • La seconda è la fase INVOKE e viene eseguita senza errori.

  • Ad un certo punto, supponiamo che la funzione abbia un errore di richiamo (le cause più comuni includono timeout delle funzioni, errori di runtime, esaurimento della memoria, problemi di connettività VPC, errori di autorizzazione, limiti di concorrenza e vari problemi di configurazione). Per un elenco completo dei possibili errori di richiamo, consulta. Risoluzione dei problemi di invocazione in Lambda La terza fase, denominata INVOKE WITH ERROR, mostra questo scenario.

    In questo caso, il servizio Lambda esegue un ripristino. Il reset si comporta come un evento Shutdown. Innanzitutto Lambda chiude il runtime, poi invia un evento Shutdown a ogni estensione esterna registrata. L'evento include il motivo dell'arresto. Se questo ambiente viene utilizzato per una nuova chiamata, Lambda re-inizializza l'estensione e il runtime insieme alla chiamata successiva.

    Nota che il ripristino di Lambda non cancella il contenuto della /tmp directory prima della successiva fase di inizializzazione. Questo comportamento è coerente con la normale fase di arresto.

    Nota

    AWS sta attualmente implementando modifiche al servizio Lambda. A causa di queste modifiche, potresti notare piccole differenze tra la struttura e il contenuto dei messaggi di log di sistema e dei segmenti di traccia emessi da diverse funzioni Lambda nel tuo Account AWS.

    Se la configurazione del registro di sistema della funzione è impostata su testo normale, questa modifica influisce sui messaggi di registro acquisiti in CloudWatch Logs quando la funzione non riesce a richiamare la funzione. Gli esempi seguenti mostrano gli output dei log nei formati vecchi e nuovi.

    Queste modifiche verranno implementate nelle prossime settimane e tutte le funzioni, Regioni AWS ad eccezione della Cina e delle GovCloud regioni, passeranno all'utilizzo dei messaggi di registro e dei segmenti di traccia di nuovo formato.

    Esempio CloudWatch Output del log dei log (crash di runtime o estensione) - vecchio stile
    START RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1 Version: $LATEST
    RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1 Error: Runtime exited without providing a reason
    Runtime.ExitError
    END RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1
    REPORT RequestId: c3252230-c73d-49f6-8844-968c01d1e2e1 Duration: 933.59 ms Billed Duration: 934 ms Memory Size: 128 MB Max Memory Used: 9 MB
    Esempio CloudWatch Registra l'output del registro (timeout della funzione) - vecchio stile
    START RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21 Version: $LATEST
    2024-03-04T17:22:38.033Z b70435cc-261c-4438-b9b6-efe4c8f04b21 Task timed out after 3.00 seconds
    END RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21
    REPORT RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21 Duration: 3004.92 ms Billed Duration: 3117 ms Memory Size: 128 MB Max Memory Used: 33 MB Init Duration: 111.23 ms

    Il nuovo formato per CloudWatch i log include un status campo aggiuntivo nella REPORT riga. In caso di arresto anomalo del runtime o dell'estensione, la riga REPORT include anche un campo ErrorType.

    Esempio CloudWatch Output del registro dei log (errore di runtime o estensione): nuovo stile
    START RequestId: 5b866fb1-7154-4af6-8078-6ef6ca4c2ddd Version: $LATEST
    END RequestId: 5b866fb1-7154-4af6-8078-6ef6ca4c2ddd
    REPORT RequestId: 5b866fb1-7154-4af6-8078-6ef6ca4c2ddd Duration: 133.61 ms Billed Duration: 214 ms Memory Size: 128 MB Max Memory Used: 31 MB Init Duration: 80.00 ms Status: error Error Type: Runtime.ExitError
    Esempio CloudWatch Registra l'output del registro (timeout della funzione) - nuovo stile
    START RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Version: $LATEST
    END RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda
    REPORT RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Duration: 3016.78 ms Billed Duration: 3101 ms Memory Size: 128 MB Max Memory Used: 31 MB Init Duration: 84.00 ms Status: timeout
  • La quarta fase rappresenta la fase INVOKE, immediatamente successiva a un errore di chiamata. In questo caso Lambda inizializza nuovamente l'ambiente eseguendo nuovamente la fase INIT. Questa operazione è chiamata inizializzazione soppressa.

    Quando si verificano inizializzazioni soppresse, Lambda non segnala esplicitamente una fase INIT aggiuntiva nei log. CloudWatch Potresti invece notare che la durata nella riga REPORT include una durata INIT aggiuntiva + la durata INVOKE. Ad esempio, supponiamo di vedere i seguenti accessi: CloudWatch

    2022-12-20T01:00:00.000-08:00 START RequestId: XXX Version: $LATEST 2022-12-20T01:00:02.500-08:00 END RequestId: XXX 2022-12-20T01:00:02.500-08:00 REPORT RequestId: XXX Duration: 3022.91 ms Billed Duration: 3000 ms Memory Size: 512 MB Max Memory Used: 157 MB

    In questo esempio, la differenza tra i timestamp REPORT e START è di 2,5 secondi. Ciò non corrisponde alla durata riportata di 3022,91 millisecondi, perché la durata della INIT (inizializzazione soppressa) aggiuntiva eseguita da Lambda non viene tenuta in conto. Da questo esempio puoi capire che la fase INVOKE effettiva ha richiesto 2,5 secondi.

    Per ulteriori informazioni su questo comportamento, puoi utilizzare il Accesso ai dati di telemetria in tempo reale per le estensioni tramite l'API Telemetry. L'API di telemetria produce gli eventi INIT_START, INIT_RUNTIME_DONE e INIT_REPORT insieme a phase=invoke ogni volta che le inizializzazioni vengono soppresse tra le fasi di invocazione.

  • La quinta fase rappresenta la fase SHUTDOWN, che viene eseguita senza errori.

Fase di arresto

Quando Lambda sta per chiudere il runtime, invia un evento Shutdown a ciascuna estensione esterna registrata. Le estensioni possono utilizzare questo tempo per le attività di pulizia finali. L'evento Shutdown è una risposta a una richiesta API Next.

Limite di durata: la durata massima della fase Shutdown dipende dalla configurazione delle estensioni registrate:

  • 0 ms: funzione senza estensioni registrate

  • 500 ms: funzione con estensione interna registrata

  • 2.000 ms: funzione con una o più estensioni esterne registrate

Se il runtime o un'estensione non risponde all'evento Shutdown entro il limite, Lambda termina il processo utilizzando un segnale SIGKILL.

Dopo che la funzione e tutte le estensioni sono state completate, Lambda mantiene l'ambiente di esecuzione per qualche tempo in previsione di un'altra chiamata di funzione. Tuttavia, Lambda termina gli ambienti di esecuzione ogni poche ore per consentire gli aggiornamenti e la manutenzione del runtime, anche per le funzioni che vengono richiamate continuamente. Non si deve dare per scontato che l'ambiente di esecuzione persista all'infinito. Per ulteriori informazioni, consulta Implementazione stateless nelle funzioni.

Quando la funzione viene richiamata nuovamente, Lambda disattiva l'ambiente per il riutilizzo. Il riutilizzo dell'ambiente di esecuzione ha le seguenti implicazioni:

  • Gli oggetti dichiarati al di fuori del metodo del gestore della funzione rimangono inizializzati, fornendo ulteriore ottimizzazione quando la funzione viene nuovamente invocata. Ad esempio, se la funzione Lambda stabilisce la connessione a un database, nelle invocazioni successive viene utilizzata la connessione originaria anziché stabilirne un'altra. È consigliabile aggiungere al codice una logica per verificare l'esistenza di una connessione prima che ne venga stabilita una nuova.

  • Ogni ambiente di esecuzione fornisce da 512 MB a 10.240 MB con incrementi di 1 MB di spazio su disco nella directory /tmp. Il contenuto della directory rimane quando il contesto di esecuzione è bloccato, fornendo così una cache transitoria utilizzabile per più invocazioni. È possibile aggiungere ulteriore codice per verificare se la cache contiene i dati memorizzati. Per ulteriori informazioni sui limiti delle dimensioni della distribuzione, vedere Quote di Lambda.

  • Processi in background o callback che sono stati avviati dalla funzione Lambda e che non sono stati completati quando la funzione è terminata; riprendere se Lambda riutilizza l'ambiente di esecuzione. È necessario accertarsi che tutti i processi in background o le callback nel codice vengano completate prima che il codice sia terminato.

Avvii a freddo e latenza

Quando Lambda riceve una richiesta per eseguire una funzione tramite l'API Lambda, il servizio prepara innanzitutto un ambiente di esecuzione. Durante questa fase di inizializzazione, il servizio scarica il codice, avvia l'ambiente ed esegue qualsiasi codice di inizializzazione all'esterno del gestore principale. Infine, Lambda esegue il codice del gestore.

Diagramma che mostra le fasi di un avvio a freddo di Lambda, incluso il download del codice e la configurazione dell'ambiente di esecuzione.

In questo diagramma, i primi due passaggi di download del codice e configurazione dell'ambiente vengono spesso definiti «avvio a freddo». Questo tempo ti viene addebitato e questo aggiunge latenza alla durata complessiva della chiamata.

Al termine dell'invocazione, l'ambiente di esecuzione viene bloccato. Per migliorare la gestione e le prestazioni delle risorse, Lambda mantiene l'ambiente di esecuzione per un periodo di tempo. Durante questo periodo, se arriva un'altra richiesta per la stessa funzione, Lambda può riutilizzare l'ambiente. Questa seconda richiesta in genere termina più rapidamente, poiché l'ambiente di esecuzione è già completamente configurato. Questo è chiamato «avvio a caldo».

Le partenze a freddo si verificano in genere in meno dell'1% delle invocazioni. La durata di un avvio a freddo varia da meno di 100 ms a oltre 1 secondo. In generale, gli avviamenti a freddo sono in genere più comuni nelle funzioni di sviluppo e test rispetto ai carichi di lavoro di produzione. Questo perché le funzioni di sviluppo e test vengono in genere richiamate meno frequentemente.

Riduzione degli avvii a freddo con la simultaneità fornita

Se hai bisogno di orari di inizio delle funzioni prevedibili per il tuo carico di lavoro, la simultaneità fornita è la soluzione consigliata per garantire la latenza più bassa possibile. Questa funzionalità preinizializza gli ambienti di esecuzione, riducendo gli avviamenti a freddo.

Ad esempio, una funzione con una concorrenza prevista pari a 6 ha 6 ambienti di esecuzione preriscaldati.

Diagramma che mostra l'ottimizzazione dell'ambiente di esecuzione Lambda con un sovraccarico di inizializzazione ridotto.

Ottimizzazione dell'inizializzazione statica

L'inizializzazione statica avviene prima che il codice dell'handler inizi a essere eseguito in una funzione. Questo è il codice di inizializzazione fornito, che si trova all'esterno del gestore principale. Questo codice viene spesso utilizzato per importare librerie e dipendenze, impostare configurazioni e inizializzare le connessioni ad altri servizi.

Il seguente esempio in Python mostra l'importazione e la configurazione dei moduli e la creazione del client Amazon S3 durante la fase di inizializzazione, prima che la funzione lambda_handler venga eseguita durante la fase di invocazione.

import os import json import cv2 import logging import boto3 s3 = boto3.client('s3') logger = logging.getLogger() logger.setLevel(logging.INFO) def lambda_handler(event, context): # Handler logic...

Il maggior contributo alla latenza prima dell'esecuzione della funzione proviene dal codice di inizializzazione. Questo codice viene eseguito quando viene creato un nuovo ambiente di esecuzione per la prima volta. Il codice di inizializzazione non viene eseguito nuovamente se una invocazione utilizza un ambiente di esecuzione caldo. I fattori che influiscono sulla latenza del codice di inizializzazione includono:

  • La dimensione del pacchetto di funzioni, in termini di librerie e dipendenze importate e livelli Lambda.

  • La quantità di codice e la procedura di inizializzazione.

  • Le prestazioni delle librerie e di altri servizi nella configurazione di connessioni e altre risorse.

Esistono diversi passaggi che gli sviluppatori possono adottare per ottimizzare la latenza di inizializzazione statica. Se una funzione ha molti oggetti e connessioni, potresti essere in grado di riprogettare una singola funzione in più funzioni specializzate. Queste sono singolarmente più piccole e ognuna ha meno codice di inizializzazione.

È importante che le funzioni importino solo le librerie e le dipendenze di cui hanno bisogno. Ad esempio, se utilizzi Amazon DynamoDB solo nell' AWS SDK, puoi richiedere un singolo servizio anziché l'intero SDK. Confronta i tre esempi seguenti:

// Instead of const AWS = require('aws-sdk'), use:
const DynamoDB = require('aws-sdk/clients/dynamodb')

// Instead of const AWSXRay = require('aws-xray-sdk'), use:
const AWSXRay = require('aws-xray-sdk-core')

// Instead of const AWS = AWSXRay.captureAWS(require('aws-sdk')), use:
const dynamodb = new DynamoDB.DocumentClient()
AWSXRay.captureAWSClient(dynamodb.service)

L'inizializzazione statica è spesso anche il posto migliore per aprire connessioni al database per consentire a una funzione di riutilizzare le connessioni su più invocazioni allo stesso ambiente di esecuzione. Tuttavia, potreste avere un numero elevato di oggetti che vengono utilizzati solo in determinati percorsi di esecuzione della funzione. In questo caso, puoi caricare lentamente le variabili nell'ambito globale per ridurre la durata dell'inizializzazione statica.

Evitate le variabili globali per informazioni specifiche del contesto. Se la funzione ha una variabile globale che viene utilizzata solo per la durata di una singola invocazione e viene reimpostata per l'invocazione successiva, utilizza un ambito di variabile locale per l'handler. In questo modo non solo si evitano perdite di variabili globali tra le invocazioni, ma si migliorano anche le prestazioni dell'inizializzazione statica.