Modalità di gestione delle istanze

Le istanze sono i componenti di base di base di App Engine e forniscono tutte le risorse necessarie per ospitare correttamente l'applicazione. In un dato momento, l'applicazione può essere in esecuzione su una o più istanze e le richieste vengono distribuite su tutte. Ogni istanza include un livello di sicurezza per garantire che non possano influenzarsi inavvertitamente l'una sull'altra.

App Engine può creare e arrestare automaticamente le istanze quando il traffico fluttua, oppure puoi specificare un numero di istanze da eseguire indipendentemente dalla quantità di traffico. Per determinare come e quando vengono create nuove istanze, devi specificare un tipo di scalabilità per la tua app. Le impostazioni di scalabilità vengono applicate a livello di versione di App Engine come parte del file app.yaml.

Tipi di scalabilità

App Engine supporta i seguenti tipi di scalabilità, che controllano come e quando vengono create le istanze:

  • Automatica (impostazione predefinita)
  • Base
  • Manuale

Puoi specificare il tipo di scalabilità nella sezione app.yaml della tua app. Per impostazione predefinita, l'applicazione utilizza la scalabilità automatica, il che significa che App Engine gestirà il numero di istanze inattive.

Scalabilità automatica
La scalabilità automatica crea istanze in base al tasso di richieste, alle latenze di risposta e ad altre metriche delle applicazioni. Puoi specificare le soglie per ciascuna di queste metriche, nonché un numero minimo di istanze da mantenere sempre in esecuzione configurando l'elemento automatic_scaling.
Scalabilità di base
La scalabilità di base crea istanze quando l'applicazione riceve richieste. Ogni istanza verrà arrestata quando l'applicazione diventerà inattiva. La scalabilità di base è ideale per attività intermittenti o basate sull'attività utente.
Scalabilità manuale
La scalabilità manuale specifica il numero di istanze in esecuzione continua indipendentemente dal livello di carico. Ciò consente attività come inizializzazioni complesse e applicazioni che dipendono dallo stato della memoria nel tempo.
Questa tabella mette a confronto le funzionalità relative alle prestazioni dei tre tipi di scalabilità:

Funzionalità Scalabilità automatica Scalabilità di base Scalabilità manuale
Timeout richiesta Dieci minuti per le richieste HTTP e le attività coda di attività. Se la tua app non restituisce una richiesta entro questo limite di tempo, App Engine interrompe il gestore delle richieste ed emette un errore da gestire con il codice.

Per i runtime legacy (Java 8, PHP 5 e Python 2):

  • Il timeout per le attività della coda di attività e le richieste da parte dei cron job è di 10 minuti.
  • Il timeout per le altre richieste HTTP è 1 minuto.
24 ore per le richieste HTTP e le attività coda di attività. Se la tua app non restituisce una richiesta entro questo limite di tempo, App Engine interrompe il gestore delle richieste ed emette un errore da gestire con il codice.

Un'istanza con scalabilità di base può scegliere di gestire /_ah/start ed eseguire un programma o script per molte ore senza restituire un codice di risposta HTTP.

Uguale alla scalabilità di base.
Residenza Le istanze vengono arrestate in base ai modelli di utilizzo. Le istanze vengono arrestate in base al parametro idle_timeout. Se un'istanza è stata inattiva, ad esempio non ha ricevuto una richiesta per più di idle_timeout, viene arrestata. Le istanze rimangono in memoria e lo stato viene mantenuto tra le richieste. Quando le istanze vengono arrestate, viene visualizzata una richiesta /_ah/stop nei log. Se esiste un gestore /_ah/stop, ha 30 secondi di tempo per completare l'operazione prima che venga eseguito l'arresto.
Avvio e arresto Le istanze vengono create on demand per gestire le richieste e vengono disattivate automaticamente quando inattive. Le istanze vengono create on demand per gestire le richieste e arrestate automaticamente quando inattive, in base al parametro di configurazione idle_timeout. Un'istanza interrotta manualmente ha 30 secondi per completare la gestione delle richieste prima di essere arrestata forzatamente. Alle istanze viene inviata automaticamente una richiesta di avvio da App Engine sotto forma di richiesta GET vuota a /_ah/start. Come per la scalabilità di base, un'istanza fermata manualmente ha 30 secondi per completare la gestione delle richieste prima di essere arrestata forzatamente.
Indirizzabilità delle istanze Le istanze sono anonime. L'istanza "i" della versione "v" del servizio "s" è indirizzabile all'URL: https://i-dot-v-dot-s-dot-app_id.REGION_ID.r.appspot.com. Se hai configurato una mappatura di un sottodominio con caratteri jolly per un dominio personalizzato, puoi anche indirizzare un servizio o una qualsiasi delle sue istanze tramite un URL nel formato https://s.domain.com o https://i.s.domain.com. Puoi memorizzare nella cache lo stato in modo affidabile in ogni istanza e recuperarlo nelle richieste successive. Uguale alla scalabilità di base.
Scalabilità App Engine scala il numero di istanze automaticamente in risposta al volume di elaborazione. Questo fattore di scalabilità tiene conto delle impostazioni automatic_scaling fornite in base alla versione nel file di configurazione. Per configurare un servizio con scalabilità di base, viene impostato il numero massimo di istanze nel parametro max_instances dell'impostazione basic_scaling. Il numero di istanze attive viene scalato in base al volume di elaborazione. Puoi configurare il numero di istanze di ogni versione nel file di configurazione del servizio in questione. Il numero di istanze corrisponde solitamente alle dimensioni di un set di dati conservato in memoria o alla velocità effettiva desiderata per il lavoro offline.

Scalabilità delle istanze dinamiche

Le applicazioni App Engine che utilizzano la scalabilità di base o automatica utilizzano un numero illimitato di istanze dinamiche in un determinato momento, a seconda del volume delle richieste in arrivo. Con l'aumento delle richieste per la tua applicazione, può aumentare anche il numero di istanze dinamiche.

App con scalabilità di base

Se utilizzi la scalabilità di base, App Engine cerca di mantenere basso i costi, anche se ciò può comportare una latenza maggiore con l'aumento del volume delle richieste in entrata.

Quando nessuna delle istanze esistenti è disponibile per gestire una richiesta in entrata, App Engine avvia una nuova istanza. Anche dopo l'avvio di una nuova istanza, alcune richieste potrebbero dover essere messe in coda fino a quando la nuova istanza non completa il processo di avvio. Se hai bisogno di ottenere la minore latenza possibile, valuta l'utilizzo della scalabilità automatica, che crea preventivamente nuove istanze per ridurre al minimo la latenza.

App con scalabilità automatica

Se utilizzi la scalabilità automatica, ogni istanza nell'app ha la propria coda per le richieste in arrivo. Prima che le code diventino abbastanza lunghe da avere un effetto notevole sulla latenza dell'applicazione, App Engine crea automaticamente una o più nuove istanze per gestire l'aumento del carico.

Puoi configurare le impostazioni per la scalabilità automatica per ottenere un compromesso tra le prestazioni e il costo che puoi sostenere. Queste impostazioni sono descritte nella tabella seguente.

Impostazioni di scalabilità automatica Descrizione
Utilizzo CPU target Imposta la soglia per il rapporto di utilizzo della CPU per specificare la soglia di utilizzo della CPU entro la quale verranno avviate altre istanze per gestire il traffico.
Utilizzo velocità effettiva target Imposta la soglia di velocità effettiva per il numero di richieste in parallelo, dopodiché altre istanze verranno avviate a gestire il traffico.
Numero massimo di richieste in parallelo Imposta il numero massimo di richieste in parallelo che un'istanza può accettare prima che lo scheduler generi una nuova istanza.

Guarda il video Scheduler Settings di App Engine per vedere gli effetti di queste impostazioni.

Scale down

Con la diminuzione del volume delle richieste, App Engine riduce il numero di istanze. Questa scalabilità verso il basso aiuta a garantire che tutte le istanze attuali dell'applicazione vengano utilizzate per ottimizzare l'efficienza e la convenienza in termini di costi.

Quando un'applicazione non viene utilizzata, App Engine disattiva le istanze dinamiche associate, ma le ricarica immediatamente appena necessario. Il ricaricamento delle istanze può comportare richieste di caricamento e una maggiore latenza per gli utenti.

Puoi specificare un numero minimo di istanze inattive. L'impostazione di un numero appropriato di istanze inattive per l'applicazione in base al volume delle richieste consente all'applicazione di gestire ogni richiesta con poca latenza, a meno che non si riscontri un volume insolitamente elevato di richieste.

Scale down nella scalabilità automatica

Se la tua app utilizza la scalabilità automatica, sono necessari circa 15 minuti di inattività prima che le istanze inattive inizino a arrestarsi. Per mantenere in esecuzione una o più istanze inattive, imposta il valore di min_idle_instances su 1 o superiore.

Scalabilità e batch di richieste

Se invii batch di richieste ai tuoi servizi, ad esempio a una coda di attività per l'elaborazione, verrà creato rapidamente un numero elevato di istanze. Ti consigliamo di controllare questa opzione limitando la frequenza di invio del numero di richieste al secondo, se possibile. Ad esempio, se utilizzi Google Tasks, puoi controllare la frequenza con cui vengono inviate le attività.

Ciclo di vita di un'istanza

Stati delle istanze

Un'istanza di un servizio con scalabilità automatica è sempre in esecuzione. Tuttavia, un'istanza di un servizio scalato manuale o di base può essere in esecuzione o arrestata. Tutte le istanze dello stesso servizio e della stessa versione condividono lo stesso stato. Puoi modificare lo stato delle istanze gestendo le versioni. Puoi:

Avvio

Ogni istanza di servizio viene creata in risposta a una richiesta di avvio, ovvero una richiesta HTTP GET vuota verso /_ah/start. App Engine invia questa richiesta per creare un'istanza; gli utenti non possono inviare una richiesta a /_ah/start. Le istanze di scalabilità manuale e di base devono rispondere alla richiesta di avvio prima di poter gestire un'altra richiesta. La richiesta di avvio può essere utilizzata per due scopi:

  • Per avviare un programma che viene eseguito a tempo indeterminato, senza accettare ulteriori richieste.
  • a inizializzare un'istanza prima che riceva traffico aggiuntivo.

Le istanze con scalabilità manuale, di base e automatica vengono avviate in modo diverso. Quando avvii un'istanza con scalabilità manuale, App Engine invia immediatamente una richiesta /_ah/start a ciascuna istanza. Quando avvii un'istanza di un servizio di scalabilità di base, App Engine consente di accettare il traffico, ma la richiesta /_ah/start non viene inviata a un'istanza finché questa non riceve la prima richiesta dell'utente. Più istanze di scalabilità di base vengono avviate solo se necessario, al fine di gestire l'aumento del traffico. Le istanze con scalabilità automatica non ricevono richieste /_ah/start.

Quando un'istanza risponde alla richiesta /_ah/start con un codice di stato HTTP di 200–299 o 404, viene considerata avviata correttamente e può gestire richieste aggiuntive. In caso contrario, App Engine termina l'istanza. Le istanze con scalabilità manuale vengono riavviate immediatamente, mentre quelle di base vengono riavviate solo quando necessario per gestire il traffico.

Arresto

Il processo di arresto potrebbe essere attivato da una serie di eventi pianificati e non pianificati, ad esempio:

  • Troppe istanze e richieste di app insufficienti (traffico).
  • Puoi arrestare manualmente un'istanza.
  • Esegui il deployment di una versione aggiornata nel servizio.
  • L'istanza supera la memoria massima per le istanze instance_class configurate.
  • L'applicazione esaurisce la quota Ore istanza.
  • L'istanza viene spostata in un'altra macchina perché la macchina attuale su cui è in esecuzione l'istanza viene riavviata oppure perché App Engine ha spostato l'istanza per migliorare la distribuzione del carico.

Uno dei vantaggi della piattaforma "Paga solo per ciò che ti serve " dell'ambiente standard di App Engine, come descritto in precedenza nella sezione Scalabilità verticale, è che il sistema scala automaticamente il numero di istanze fino a zero in assenza di traffico. Ciò rende App Engine una soluzione economica per le piccole applicazioni che non ricevono richieste continue. Quando un'istanza deve essere arrestata, le nuove richieste in entrata vengono instradate ad altre istanze (se presenti) e le richieste attualmente in fase di elaborazione hanno il tempo di essere completato.

Quando un'istanza deve essere arrestata, App Engine invia un indicatore KILL (SIGKILL), terminando l'istanza.

Caricamento richieste in corso...

Quando App Engine crea una nuova istanza per l'applicazione, questa deve prima caricare le librerie e le risorse necessarie per gestire la richiesta. Questo avviene durante la prima richiesta all'istanza, denominata Richiesta di caricamento. Durante una richiesta di caricamento, l'applicazione viene inizializzata, il che significa che la richiesta richiede più tempo.

Le seguenti best practice consentono di ridurre la durata delle richieste di caricamento:

  • Carica solo il codice necessario per l'avvio.
  • Accedi al disco il meno possibile.
  • In alcuni casi, il caricamento del codice da un file ZIP o jar è più veloce rispetto al caricamento da molti file separati.

Richieste di warmup

Le richieste di warmup sono un tipo specifico di richiesta di caricamento che carica il codice dell'applicazione in un'istanza in anticipo, prima di qualsiasi richiesta in tempo reale. Le istanze di scalabilità manuale o di base non ricevono una richiesta /_ah/warmup.

Per scoprire di più su come utilizzare le richieste di warmup, consulta Configurazione delle richieste di warmup.

Uptime delle istanze

App Engine tenta di mantenere in esecuzione indefinitamente le istanze di scalabilità manuali e di base. Tuttavia, al momento non è garantito un tempo di attività per le istanze con scalabilità manuale e di base. I guasti hardware e software che causano la risoluzione anticipata o riavvii frequenti possono verificarsi senza preavviso e la loro risoluzione può richiedere molto tempo; pertanto, devi creare la tua applicazione in modo che tollera questi errori.

Di seguito sono riportate alcune buone strategie per evitare tempi di inattività dovuti al riavvio delle istanze:

  • Riduci il tempo necessario per il riavvio delle istanze o l'avvio di nuove istanze.
  • Per i calcoli a lunga esecuzione, crea periodicamente checkpoint per riprendere da quello stato.
  • L'app deve essere "stateless" per fare in modo che non venga archiviato nulla nell'istanza.
  • Utilizza le code per eseguire l'esecuzione asincrona delle attività.
  • Se configuri le istanze con scalabilità manuale:
    • Utilizza il bilanciamento del carico su più istanze.
    • Configura più istanze del necessario per gestire il traffico normale.
    • Scrivi una logica di fallback che utilizza i risultati memorizzati nella cache quando non è disponibile un'istanza di scalabilità manuale.

NTP con ambiente standard di App Engine

L'ambiente standard di App Engine dispone di servizi NTP (Network Time Protocol) che utilizzano server NTP di Google. Tuttavia, il servizio NTP non è modificabile.