Modalità di gestione delle richieste

ID regione

REGION_ID è un codice abbreviato assegnato da Google in base all'area geografica selezionata al momento della creazione dell'app. Il codice non corrisponde a un paese o a una provincia, anche se alcuni ID di area geografica potrebbero essere simili ai codici di paese e provincia di uso comune. Per le app create dopo febbraio 2020, REGION_ID.r è incluso negli URL di App Engine. Per le app esistenti create prima di questa data, l'ID area geografica è facoltativo nell'URL.

Scopri di più sugli ID dell'area geografica.

Questo documento descrive il modo in cui l'applicazione App Engine riceve le richieste e invia le risposte. Per ulteriori dettagli, consulta il riferimento per le intestazioni e le risposte delle richieste.

Se la tua applicazione utilizza servizi, puoi indirizzare le richieste a un servizio specifico o a una versione specifica di quel servizio. Per ulteriori informazioni sull'indirizzabilità del servizio, vedi Modalità di routing delle richieste.

Gestione delle richieste

L'applicazione è responsabile dell'avvio di un server web e della gestione delle richieste. Puoi utilizzare qualsiasi framework web disponibile per il tuo linguaggio di sviluppo.

App Engine esegue più istanze dell'applicazione e ogni istanza dispone di un proprio server web per la gestione delle richieste. Qualsiasi richiesta può essere instradata a qualsiasi istanza, pertanto le richieste consecutive dello stesso utente non vengono necessariamente inviate alla stessa istanza. Un'istanza può gestire più richieste contemporaneamente. Il numero di istanze può essere modificato automaticamente in base alle variazioni del traffico. Puoi anche cambiare il numero di richieste in parallelo che un'istanza è in grado di gestire impostando l'elemento max_concurrent_requests nel file app.yaml.

Il runtime Go per App Engine utilizza il http pacchetto standard come interfaccia tra il tuo programma Go e i server di App Engine. Quando App Engine riceve una richiesta web per la tua applicazione, richiama http.Handler associato all'URL della richiesta.

L'esempio riportato di seguito è un'app Go completa che restituisce una stringa HTML hardcoded all'utente:


// Sample helloworld is an App Engine app.
package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)

func main() {
	http.HandleFunc("/", indexHandler)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("Defaulting to port %s", port)
	}

	log.Printf("Listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}

// indexHandler responds to requests with our greeting.
func indexHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}
	fmt.Fprint(w, "Hello, World!")
}

Quote e limiti

App Engine alloca automaticamente le risorse all'applicazione in base all'aumento del traffico. Tuttavia, ciò è vincolato dalle seguenti limitazioni:

  • App Engine prenota la capacità di scalabilità automatica per le applicazioni con bassa latenza, in cui l'applicazione risponde alle richieste in meno di un secondo.

  • Le applicazioni fortemente associate alla CPU possono inoltre comportare una latenza aggiuntiva per condividere in modo efficiente le risorse con altre applicazioni sugli stessi server. Le richieste di file statici sono esenti da questi limiti di latenza.

Ogni richiesta in entrata per l'applicazione viene conteggiata ai fini del limite di richieste. I dati inviati in risposta a una richiesta vengono conteggiati ai fini del limite di larghezza di banda in uscita (fatturabile).

Sia le richieste HTTP che HTTPS (protette) vengono conteggiate ai fini dei limiti Richieste, Larghezza di banda in entrata (fatturabile) e Larghezza di banda in uscita (fatturabile). La pagina dei dettagli delle quote di Cloud Console indica anche Richieste sicure, Larghezza di banda in entrata sicura e Larghezza di banda in uscita sicura come valori separati a scopo informativo. Solo le richieste HTTPS vengono conteggiate per questi valori. Per ulteriori informazioni, consulta la pagina Quote.

I seguenti limiti sono applicabili in modo specifico all'utilizzo dei gestori di richieste:

Limite Quantità
Dimensioni richiesta 32 megabyte
Dimensione della risposta 32 megabyte
Timeout richiesta Dipende dal tipo di scalabilità utilizzata dall'app.
Numero massimo totale di file (file per app e file statici) 10.000 in totale
1000 per directory
Dimensione massima di un file di applicazione 32 megabyte
Dimensione massima di un file statico 32 megabyte
Dimensione massima totale di tutti i file statici e dell'applicazione Il primo gigabyte è gratuito
$ 0,026 per gigabyte al mese dopo il primo gigabyte
Timeout della richiesta in attesa 10 secondi
Dimensione massima di un singolo campo di intestazione della richiesta 8 kilobyte per runtime di seconda generazione nell'ambiente standard. Le richieste a questi runtime con campi di intestazione che superano gli 8 kilobyte restituiranno errori HTTP 400.

Limiti per le richieste

Tutte le richieste HTTP/2 verranno tradotte in richieste HTTP/1.1 quando inoltrate al server delle applicazioni.

Limiti di risposta

  • Le risposte dinamiche sono limitate a 32 MB. Se un gestore di script genera una risposta più grande di questo limite, il server restituisce una risposta vuota con un codice di stato di errore interno del server 500. Questa limitazione non si applica alle risposte che forniscono dati dall'archivio BLOB precedente o da Cloud Storage.

  • Il limite di intestazione della risposta è 8 kB per i runtime di seconda generazione. Le intestazioni delle risposte che superano questo limite restituiranno errori HTTP 502, con i log che mostrano upstream sent too big header while reading response header from upstream.

Intestazioni delle richieste

Una richiesta HTTP in entrata include le intestazioni HTTP inviate dal client. Per motivi di sicurezza, alcune intestazioni vengono purificate o modificate da proxy intermedi prima che raggiungano l'applicazione.

Per ulteriori informazioni, consulta il riferimento per le intestazioni delle richieste.

Gestione dei timeout delle richieste

App Engine è ottimizzato per applicazioni con richieste di breve durata, che di solito richiedono poche centinaia di millisecondi. Un'app efficiente risponde rapidamente per la maggior parte delle richieste. Un'app che non raggiunge una certa scalabilità con l'infrastruttura di App Engine. Per garantire questo livello di prestazioni, è previsto un timeout massimo imposto dal sistema a cui ogni app deve rispondere.

Se la tua app supera questa scadenza, App Engine interrompe il gestore delle richieste. Per i gestori delle richieste Go, il processo viene arrestato e l'ambiente di runtime restituisce un errore HTTP 500 Internal Server al client.

Risposte

App Engine chiama il gestore con un Request e un ResponseWriter, quindi attende che il gestore scriva al ResponseWriter e lo restituisca. Quando il gestore restituisce, i dati nel buffer interno di ResponseWriter vengono inviati all'utente.

Praticamente come quando scrivi programmi Go standard che utilizzano il pacchetto http.

Esistono limiti di dimensione che si applicano alla risposta generata e la risposta può essere modificata prima che venga restituita al client.

Per ulteriori informazioni, consulta il riferimento per le richieste di risposta.

Risposte in streaming

App Engine non supporta risposte di flussi di dati in cui i dati vengono inviati in blocchi incrementali al client durante l'elaborazione di una richiesta. Tutti i dati del codice vengono raccolti come descritto sopra e inviati come singola risposta HTTP.

Compressione delle risposte

Per le risposte restituite dal codice, App Engine comprime i dati nella risposta se si verificano entrambe le seguenti condizioni:

  • La richiesta contiene l'intestazione Accept-Encoding che include gzip come valore.
  • La risposta contiene dati basati su testo come HTML, CSS o JavaScript.

Per le risposte restituite da un gestore di file o directory statico di App Engine, i dati di risposta vengono compressi se tutte le condizioni seguenti sono vere:

  • La richiesta include Accept-Encoding con gzip come uno dei suoi valori.
  • Il client è in grado di ricevere i dati di risposta in un formato compresso. Google Frontend gestisce un elenco di client che notoriamente presentano problemi di risposte compresse. Questi client non riceveranno dati compressi dai gestori statici della tua app, anche se le intestazioni della richiesta contengono Accept-Encoding: gzip.
  • La risposta contiene dati basati su testo come HTML, CSS o JavaScript.

Tieni presente quanto segue:

  • Un client può forzare la compressione dei tipi di contenuti basati su testo impostando entrambe le intestazioni delle richieste Accept-Encoding e User-Agent su gzip.

  • Se una richiesta non specifica gzip nell'intestazione Accept-Encoding, App Engine non comprime i dati di risposta.

  • Google Frontend memorizza nella cache le risposte dai gestori di file statici e directory di App Engine. A seconda di vari fattori, ad esempio il tipo di dati di risposta memorizzati nella cache, le intestazioni Vary specificate nella risposta e le intestazioni incluse nella richiesta, un client può richiedere dati compressi, ma ricevere dati non compressi e viceversa. Per ulteriori informazioni, consulta la sezione relativa alla memorizzazione nella cache delle risposte.

Memorizzazione nella cache delle risposte

Il front-end di Google e, potenzialmente, il browser dell'utente e altri server proxy con memorizzazione nella cache memorizzano nella cache le risposte alle app in base alle istruzioni presenti nelle intestazioni standard di memorizzazione nella cache da te specificate nella risposta. Puoi specificare queste intestazioni di risposta tramite il framework, direttamente nel tuo codice o tramite i gestori statici di file e directory di App Engine.

Nel Google Frontend, la chiave della cache è l'URL completo della richiesta.

Memorizzazione nella cache dei contenuti statici

Per garantire che i client ricevano sempre contenuti statici aggiornati non appena vengono pubblicati, ti consigliamo di pubblicare contenuti statici provenienti da directory con versione, ad esempio css/v1/styles.css. Il Google Frontend non convaliderà la cache (controlla se sono presenti contenuti aggiornati) fino alla scadenza della cache. Anche dopo la scadenza della cache, la cache non viene aggiornata fino a quando i contenuti dell'URL della richiesta non cambiano.

Le seguenti intestazioni di risposta che è possibile impostare in app.yaml influiscono su come e quando Google Frontend memorizza i contenuti nella cache:

  • Cache-Control deve essere impostato su public affinché il Google Frontend possa memorizzare nella cache i contenuti; può essere memorizzato nella cache anche dal Google Frontend, a meno che non specifichi un'istruzione Cache-Control private o no-store. Se non imposti questa intestazione in app.yaml, App Engine la aggiunge automaticamente per tutte le risposte gestite da un gestore di file o directory statico. Per ulteriori informazioni, consulta la sezione Intestazioni aggiunte o sostituite.

  • Vary: per consentire alla cache di restituire risposte diverse per un URL in base alle intestazioni inviate nella richiesta, imposta uno o più dei seguenti valori nell'intestazione della risposta Vary: Accept, Accept-Encoding, Origin o X-Origin

    A causa della potenziale alta cardinalità, i dati non verranno memorizzati nella cache per altri valori di Vary.

    Ad esempio:

    1. Devi specificare la seguente intestazione della risposta:

      Vary: Accept-Encoding

    2. La tua app riceve una richiesta contenente l'intestazione Accept-Encoding: gzip. App Engine restituisce una risposta compressa e il Google Frontend memorizza nella cache la versione gzip dei dati di risposta. Tutte le successive richieste per questo URL che contengono l'intestazione Accept-Encoding: gzip riceveranno i dati compressi dalla cache fino a quando la cache non verrà annullata (a causa dei contenuti che cambiano dopo la scadenza della cache).

    3. La tua app riceve una richiesta che non contiene l'intestazione Accept-Encoding. App Engine restituisce una risposta non compressa e Google Frontend memorizza nella cache la versione non compressa dei dati di risposta. Tutte le successive richieste per questo URL che non contengono l'intestazione Accept-Encoding riceveranno i dati compressi dalla cache fino a quando la cache non viene annullata.

    Se non specifichi un'intestazione di risposta Vary, Google Frontend crea una singola voce della cache per l'URL e la utilizza per tutte le richieste indipendentemente dalle intestazioni nella richiesta. Ad esempio:

    1. Non è specificata l'intestazione della risposta Vary: Accept-Encoding.
    2. Una richiesta contiene l'intestazione Accept-Encoding: gzip e la versione gzip dei dati di risposta verrà memorizzata nella cache.
    3. Una seconda richiesta non contiene l'intestazione Accept-Encoding: gzip. Tuttavia, poiché la cache contiene una versione gzip dei dati di risposta, la risposta verrà compressa anche se il client ha richiesto dati non compressi.

Anche le intestazioni della richiesta influiscono sulla memorizzazione nella cache:

  • Se la richiesta contiene un'intestazione Authorization, i contenuti non verranno memorizzati nella cache dal Google Frontend.

Scadenza cache

Per impostazione predefinita, le intestazioni di memorizzazione nella cache che i gestori di file e directory statici di App Engine aggiungono alle risposte indicano ai client e ai proxy web come il Google Frontend di far scadere la cache dopo 10 minuti.

Dopo che un file è stato trasmesso con una data di scadenza, di solito non è possibile cancellare le cache del proxy web, anche se l'utente svuota la cache del browser. Il nuovo deployment di una nuova versione dell'app non reimposta le cache. Pertanto, se prevedi di modificare un file statico, questo dovrebbe avere una scadenza breve (meno di un'ora). Nella maggior parte dei casi, la scadenza predefinita di 10 minuti è appropriata.

Puoi modificare la scadenza predefinita di tutti i gestori di file e directory statici specificando l'elemento default_expiration nel tuo app.yaml file. Per impostare tempi di scadenza specifici per i gestori individiual, specifica l'elemento expiration all'interno dell'elemento gestore nel file app.yaml.

Il valore specificato nel periodo dell'elemento di scadenza verrà utilizzato per impostare le intestazioni della risposta HTTP Cache-Control e Expires.

Forzare le connessioni HTTPS

Per motivi di sicurezza, tutte le applicazioni devono incoraggiare i client a connettersi tramite https. Per indicare al browser di preferire https rispetto a http per una determinata pagina o per l'intero dominio, imposta l'intestazione Strict-Transport-Security nelle risposte. Ad esempio:

Strict-Transport-Security: max-age=31536000; includeSubDomains
Per impostare questa intestazione per tutti i contenuti statici pubblicati dalla tua app, aggiungi l'intestazione ai gestori statici della directory e dei file dell'app.

Per impostare questa intestazione per le risposte generate dal codice, utilizza il pacchetto secureheader.

Gestione del lavoro asincrono in background

Per lavoro in background si intende qualsiasi lavoro eseguito dalla tua app per una richiesta dopo che hai consegnato la risposta HTTP. Evita di eseguire operazioni in background nell'app ed esamina il codice per assicurarti che tutte le operazioni asincrone siano completate prima di inviare la risposta.

Per i job a lunga esecuzione, consigliamo di utilizzare Cloud Tasks. Con Cloud Tasks, le richieste HTTP sono a lungo termine e restituiscono una risposta solo al termine di un lavoro asincrono.