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 regione possono sembrare simili ai codici 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 regione è facoltativo nell'URL.

Scopri di più sugli ID regione.

Questo documento descrive in che modo l'applicazione App Engine riceve richieste e invia risposte.

Per maggiori dettagli, consulta il riferimento su intestazioni e risposte delle richieste.

Se la tua applicazione utilizza i servizi, puoi indirizzare le richieste a un servizio specifico o a una versione specifica del servizio. Per maggiori informazioni sull'indirizzabilità dei servizi, 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, ciascuna con 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 modificare il numero di richieste in parallelo che un'istanza può gestire impostando l'elemento max_concurrent_requests nel file app.yaml.

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

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


// 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 risorse alla tua applicazione quando il traffico aumenta. Tuttavia, ciò è vincolato dalle seguenti limitazioni:

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

  • Le applicazioni che sono fortemente legate alla CPU possono comportare anche 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 nell'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 Dettagli delle quote della console Google Cloud riporta anche le Richieste sicure, la Larghezza di banda in entrata sicura e la 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 si applicano in modo specifico all'uso dei gestori delle richieste:

Limite Quantità
Dimensioni richiesta 32 megabyte
Dimensione della risposta 32 megabyte
Timeout richiesta Dipende dal tipo di scalabilità utilizzata dall'app
Numero totale massimo di file (file di app e file statici) 10.000 in totale
1000 per directory
Dimensioni massime del file di un'applicazione 32 megabyte
Dimensione massima di un file statico 32 megabyte
Dimensioni totali massime di tutti i file statici e delle applicazioni Il primo gigabyte è gratuito
0,026$ per gigabyte al mese dopo il primo gigabyte
Timeout richiesta in attesa 10 secondi
Dimensione massima di un singolo campo di intestazione della richiesta 8 kilobyte per i 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 risposte

  • Le risposte dinamiche non possono superare i 32 MB. Se un gestore di script genera una risposta maggiore di questo limite, il server restituisce una risposta vuota con un codice di stato 500 Internal Server Error. Questa limitazione non si applica alle risposte che forniscono dati dall'archivio BLOB legacy o da Cloud Storage.

  • Il limite delle intestazioni delle risposte è di 8 kB per i runtime di seconda generazione. Le intestazioni delle risposte che superano questo limite restituiranno errori HTTP 502 e i log 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 sanitizzate o modificate da proxy intermedi prima che raggiungano l'applicazione.

Per saperne di più, consulta la sezione di riferimento sulle intestazioni delle richieste.

Gestione dei timeout delle richieste

App Engine è ottimizzato per applicazioni con richieste di breve durata, in genere quelle che richiedono alcune centinaia di millisecondi. Un'app efficiente risponde velocemente alla maggior parte delle richieste. Un'app che non può scalare bene con l'infrastruttura di App Engine. Per garantire questo livello di prestazioni, è previsto un timeout della richiesta massimo imposto dal sistema entro il quale ogni app deve rispondere.

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

Risposte

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

Praticamente come quando si scrivono normali programmi Go che utilizzano il pacchetto http.

Alla risposta generata si applicano dei limiti di dimensione, che possono essere modificate prima di essere restituita al client.

Per saperne di più, consulta il riferimento alle richieste di risposte.

Risposte dinamiche

App Engine non supporta risposte in modalità flusso in cui i dati vengono inviati al client in blocchi incrementali durante l'elaborazione di una richiesta. Tutti i dati del codice vengono raccolti come descritto in precedenza e inviati come un'unica risposta HTTP.

Compressione delle risposte

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

  • La richiesta contiene l'intestazione Accept-Encoding che include gzip come valore.
  • La risposta contiene dati di tipo testuale, come HTML, CSS o JavaScript.

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

  • La richiesta include Accept-Encoding con gzip come uno dei valori.
  • Il client è in grado di ricevere i dati di risposta in un formato compresso. Google Frontend gestisce un elenco di client che notano problemi con le risposte compresse. Questi client non riceveranno dati compressi da gestori statici nella tua app, anche se le intestazioni delle richieste contengono Accept-Encoding: gzip.
  • La risposta contiene dati di tipo testuale, come HTML, CSS o JavaScript.

Tieni presente quanto segue:

  • Un client può forzare la compressione di 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 comprimerà i dati della risposta.

  • Google Frontend memorizza nella cache le risposte dei gestori di directory e file statici di App Engine. A seconda di una serie di fattori, come il tipo di dati delle risposte memorizzati nella cache per primi, 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 Memorizzazione nella cache delle risposte.

Memorizzazione nella cache delle risposte

Il Google Frontend e, potenzialmente, il browser dell'utente e altri server proxy con memorizzazione nella cache intermedia, memorizzano nella cache le risposte dell'app, come indicato dalle intestazioni di memorizzazione nella cache standard specificate nella risposta. Puoi specificare queste intestazioni delle risposte tramite il framework, direttamente nel codice oppure tramite i gestori di file e directory statici di App Engine.

In Google Frontend, la chiave cache corrisponde all'URL completo della richiesta.

Memorizzazione nella cache dei contenuti statici

Per fare in modo che i client ricevano sempre i contenuti statici aggiornati non appena vengono pubblicati, ti consigliamo di pubblicare contenuti statici dalle directory con il controllo delle versioni, ad esempio css/v1/styles.css. Google Frontend non convaliderà la cache (verifica la presenza di contenuti aggiornati) fino alla scadenza della cache. Anche dopo la scadenza, la cache non verrà aggiornata fino a quando i contenuti all'URL della richiesta non verranno modificati.

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

  • Cache-Control deve essere impostato su public affinché Google Frontend memorizzi nella cache i contenuti; può anche essere memorizzato nella cache dal Google Frontend, a meno che non venga specificata 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 file statico o gestore di directory. Per ulteriori informazioni, consulta 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 del potenziale di una cardinalità elevata, i dati non verranno memorizzati nella cache per altri valori Vary.

    Ad esempio:

    1. Specifichi 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 Google Frontend memorizza nella cache la versione compressa con gzip dei dati della 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 sarà invalidata (a causa della modifica dei contenuti 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 della 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 verrà invalidata.

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

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

Anche le intestazioni della richiesta influenzano la memorizzazione nella cache:

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

Scadenza della cache

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

Dopo che un file è stato trasmesso con una determinata data di scadenza, in genere non è possibile svuotarlo dalle cache del proxy web, anche se l'utente svuota la cache del browser. Il deployment di una nuova versione dell'app non comporta la reimpostazione delle cache. Pertanto, se pianifichi di modificare un file statico, quest'ultimo deve avere una scadenza breve (meno di un'ora). Nella maggior parte dei casi, il valore predefinito di 10 minuti di scadenza è appropriato.

Puoi modificare la scadenza predefinita per tutti i gestori di file statici e directory specificando l'elemento default_expiration nel file app.yaml. Per impostare tempistiche di scadenza specifiche per singoli gestori, specifica l'elemento expiration nell'elemento gestore nel file app.yaml.

Il valore specificato nell'ora degli elementi 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 i contenuti statici pubblicati dalla tua app, aggiungila ai gestori di file e directory dell'app.

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

Gestione del lavoro in background asincrono

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

Per i job a lunga esecuzione, consigliamo di utilizzare Cloud Tasks. Con Cloud Tasks, le richieste HTTP hanno durata estesa e restituiscono una risposta solo al termine di qualsiasi lavoro asincrono.