ID regione
Il REGION_ID
è un codice abbreviato che Google assegna
in base alla regione selezionata durante la creazione dell'app. Il codice non
corrisponde a un paese o a una provincia, anche se alcuni ID regione possono sembrare
simili ai codici di paesi e province di uso comune. Per le app create dopo
febbraio 2020, REGION_ID.r
è incluso negli
URL 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 come l'applicazione App Engine riceve le richieste e invia le risposte.
Per maggiori dettagli, consulta la guida di riferimento per intestazioni e 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 Come vengono instradate le richieste.
Gestione delle richieste
La tua applicazione è responsabile dell'avvio di un web server 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 ha il proprio server web per la gestione delle richieste. Qualsiasi richiesta può essere indirizzata
a qualsiasi istanza, quindi 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 simultanee che un'istanza può gestire
impostando l'elemento max_concurrent_requests
nel file app.yaml.
app.yaml
dell'applicazione. Il runtime Python 2.7 supporta gli standard WSGI e CGI per la compatibilità con le versioni precedenti. WSGI è preferito e alcune funzionalità di Python 2.7 non funzionano senza. La configurazione dei gestori
di script
della tua applicazione determina se una richiesta viene gestita utilizzando WSGI o CGI.
Il seguente script Python risponde a una richiesta con un'intestazione HTTP e il messaggio Hello, World!
.
Per inviare più richieste a ogni web server in parallelo, contrassegna la tua applicazione come thread-safe aggiungendo threadsafe: true
al file app.yaml
. Le richieste simultanee non sono disponibili se un gestore di script utilizza CGI.
Quote e limiti
App Engine alloca automaticamente le risorse alla tua applicazione man mano che il traffico aumenta. Tuttavia, questa operazione è vincolata alle seguenti limitazioni:
App Engine riserva 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 con un elevato utilizzo della CPU potrebbero anche 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 all'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).
Le richieste HTTP e HTTPS (sicure) vengono conteggiate ai fini dei limiti di Richieste, Larghezza di banda in entrata (fatturabile) e Larghezza di banda in uscita (fatturabile). La Google Cloud console pagina Dettagli quota riporta anche Richieste sicure, Larghezza di banda in entrata sicura e Larghezza di banda in uscita sicura come valori separati a scopo informativo. Ai fini di questi valori, vengono conteggiate solo le richieste HTTPS. Per ulteriori informazioni, consulta la pagina Quote.
I seguenti limiti si applicano specificamente all'utilizzo dei gestori delle richieste:
Limite | Quantità |
---|---|
Dimensioni richiesta | 32 megabyte |
Dimensione della risposta | 32 megabyte |
Timeout richiesta | Dipende dal tipo di scalabilità utilizzato dalla tua app |
Numero totale massimo di file (file dell'app e file statici) | 10.000 totali 1000 per directory |
Dimensione massima di un file dell'applicazione | 32 megabyte |
Dimensione massima di un file statico | 32 megabyte |
Dimensione totale massima 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 i runtime di seconda generazione nell'ambiente standard. Le richieste a questi runtime con campi di intestazione superiori a 8 kilobyte restituiranno errori HTTP 400. |
Limiti per le richieste
Tutte le richieste HTTP/2 verranno convertite in richieste HTTP/1.1 quando vengono inoltrate al server delle applicazioni.
Limiti di risposta
Le risposte dinamiche sono limitate a 32 MB. Se un gestore di script genera una risposta superiore a 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 da Blobstore legacy o Cloud Storage.
Il limite dell'intestazione della risposta è di 8 KB per gli runtime di seconda generazione. Le intestazioni di risposta che superano questo limite restituiranno errori HTTP 502, con 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 sanificate o modificate da proxy intermedi prima di raggiungere l'applicazione.
Per maggiori informazioni, consulta la documentazione di riferimento delle intestazioni delle richieste.
Gestione dei timeout delle richieste
App Engine è ottimizzato per le applicazioni con richieste di breve durata, in genere quelle che richiedono poche centinaia di millisecondi. Un'app efficiente risponde rapidamente alla maggior parte delle richieste. Un'app che non lo fa non verrà scalata correttamente con l'infrastruttura di App Engine. Per garantire questo livello di prestazioni, esiste un timeout della richiesta massimo imposto dal sistema a cui ogni app deve rispondere.
Se la tua app supera questa scadenza, App Engine interrompe il gestore di richieste. L'ambiente di runtime Python lo fa generando un'eccezioneDeadlineExceededError
da google.appengine.runtime
. Se il gestore di richieste non rileva questa eccezione, come per tutte le eccezioni non rilevate, l'ambiente di runtime restituirà un errore del server HTTP 500 al client.
Il gestore delle richieste può rilevare questo errore per personalizzare la risposta. L'ambiente di runtime concede al gestore delle richieste un po' di tempo in più (meno di un secondo) dopo aver generato l'eccezione per preparare una risposta personalizzata.
Se il gestore non ha restituito una risposta o generato un'eccezione entro la seconda scadenza, viene interrotto e viene restituita una risposta di errore predefinita.
Risposte
App Engine chiama lo script del gestore con unRequest
e attende che lo script venga restituito. Tutti i dati scritti nel flusso di output standard vengono inviati come risposta HTTP.
Esistono limiti di dimensione che si applicano alla risposta che generi e la risposta potrebbe essere modificata prima di essere restituita al client.
Per maggiori informazioni, consulta la documentazione di riferimento sulle risposte alle richieste.Risposte dinamiche
App Engine non supporta le risposte in streaming in cui i dati vengono inviati in blocchi incrementali al client durante l'elaborazione di una richiesta. Tutti i dati del tuo codice vengono raccolti come descritto sopra e inviati come una singola risposta HTTP.
Compressione delle risposte
App Engine fa del suo meglio per pubblicare contenuti compressi (gzip) per i client che lo supportano. Per determinare se i contenuti devono essere compressi, App Engine esegue le seguenti operazioni quando riceve una richiesta:Conferma se il client può ricevere in modo affidabile risposte compresse visualizzando le intestazioni
Accept-Encoding
eUser-Agent
nella richiesta. Questo approccio evita alcuni bug noti con i contenuti compressi con gzip nei browser più diffusi.Conferma se la compressione dei contenuti è appropriata visualizzando l'intestazione
Content-Type
che hai configurato per l'handler di risposta. In generale, la compressione è adatta ai tipi di contenuti basati su testo e non ai tipi di contenuti binari.
Tieni presente quanto segue:
Un client può forzare la compressione dei tipi di contenuti basati su testo impostando entrambe le intestazioni della richiesta
Accept-Encoding
eUser-Agent
sugzip
.Se una richiesta non specifica
gzip
nell'intestazioneAccept-Encoding
, App Engine non comprimerà i dati di risposta.Il frontend di Google memorizza nella cache le risposte dei gestori di file statici e delle directory di App Engine. A seconda di una serie di fattori, ad esempio il tipo di dati di risposta memorizzati nella cache per primi, le intestazioni
Vary
specificate nella risposta e le intestazioni incluse nella richiesta, un client potrebbe richiedere dati compressi ma ricevere dati non compressi e viceversa. Per maggiori informazioni, consulta Memorizzazione nella cache delle risposte.
Memorizzazione nella cache delle risposte
Il frontend di Google e potenzialmente il browser dell'utente e altri proxy server di memorizzazione nella cache intermedi memorizzeranno nella cache le risposte della tua app come indicato dalle intestazioni di memorizzazione nella cache standard che specifichi nella risposta. Puoi specificare queste intestazioni di risposta tramite il framework, direttamente nel codice o tramite i gestori di file e directory statici di App Engine.
Nel frontend di Google, 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 da directory con controllo delle versioni, ad esempio css/v1/styles.css
. Il frontend di Google non convaliderà
la cache (non verificherà la presenza di contenuti aggiornati) finché non scade. Anche dopo la scadenza della cache, questa non verrà aggiornata finché i contenuti all'URL della richiesta non cambiano.
Le seguenti intestazioni di risposta che puoi
impostare in
app.yaml
influenzano come e quando il frontend di Google memorizza nella cache i contenuti:
Cache-Control
deve essere impostato supublic
affinché il frontend di Google memorizzi nella cache i contenuti; questi potrebbero anche essere memorizzati nella cache dal frontend di Google, a meno che tu non specifichi un'istruzioneCache-Control
private
ono-store
. Se non imposti questa intestazione inapp.yaml
, App Engine la aggiunge automaticamente a tutte le risposte gestite da un gestore di file o directory statici. 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 rispostaVary
:Accept
,Accept-Encoding
,Origin
oX-Origin
.A causa della potenziale cardinalità elevata, i dati non verranno memorizzati nella cache per altri valori di
Vary
.Ad esempio:
Specifica la seguente intestazione della risposta:
Vary: Accept-Encoding
La tua app riceve una richiesta che contiene l'intestazione
Accept-Encoding: gzip
. App Engine restituisce una risposta compressa e Google Frontend memorizza nella cache la versione compressa dei dati di risposta. Tutte le richieste successive per questo URL che contengono l'intestazioneAccept-Encoding: gzip
riceveranno i dati compressi con gzip dalla cache finché la cache non viene invalidata (a causa della modifica dei contenuti dopo la scadenza della cache).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 richieste successive per questo URL che non contengono l'intestazioneAccept-Encoding
riceveranno i dati compressi dalla cache finché la cache non diventa non valida.
Se non specifichi un'intestazione di risposta
Vary
, il frontend di Google crea una singola voce della cache per l'URL e la utilizzerà per tutte le richieste indipendentemente dalle intestazioni della richiesta. Ad esempio:- Non specifichi l'intestazione della risposta
Vary: Accept-Encoding
. - Una richiesta contiene l'intestazione
Accept-Encoding: gzip
e la versione compressa dei dati di risposta verrà memorizzata nella cache. - Una seconda richiesta non contiene l'intestazione
Accept-Encoding: gzip
. Tuttavia, poiché la cache contiene una versione compressa con gzip dei dati di risposta, la risposta verrà compressa con gzip 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 del frontend di Google.
Scadenza della cache
Per impostazione predefinita, le intestazioni di memorizzazione nella cache che i gestori di file statici e directory di App Engine aggiungono alle risposte indicano ai client e ai proxy web, come Google Frontend, di scadere la cache dopo 10 minuti.
Una volta trasmesso un file con un determinato tempo di scadenza, in genere non è possibile cancellarlo dalle cache dei proxy web, anche se l'utente svuota la propria cache del browser. Il redeployment di una nuova versione dell'app non reimposterà le cache. Pertanto, se prevedi di modificare un file statico, questo deve avere un tempo di scadenza breve (inferiore a un'ora). Nella maggior parte dei casi, il tempo di scadenza predefinito di 10 minuti è appropriato.
Puoi modificare la scadenza predefinita per tutti i gestori di file e directory statici
specificando l'elemento
default_expiration
nel file
app.yaml
. Per impostare tempi di scadenza specifici per i singoli
gestori,
specifica l'elemento expiration
all'interno dell'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
.
Memorizzazione nella cache delle app
L'ambiente di runtime Python memorizza nella cache i moduli importati tra le richieste su un singolo server web, in modo simile a come un'applicazione Python autonoma carica un modulo una sola volta anche se il modulo viene importato da più file. Poiché i gestori WSGI sono moduli, vengono memorizzati nella cache tra le richieste. Gli script di gestione CGI vengono memorizzati nella cache solo se forniscono una routinemain()
; in caso contrario, lo script di gestione CGI viene caricato per ogni richiesta.
La memorizzazione nella cache delle app offre un vantaggio significativo in termini di tempo di risposta. Ti consigliamo di utilizzare una routine main() in tutti gli script del gestore CGI, come descritto di seguito.
Le importazioni vengono memorizzate nella cache
Per efficienza, il server web mantiene i moduli importati in memoria e non li ricarica o rivaluta nelle richieste successive alla stessa applicazione sullo stesso server. La maggior parte dei moduli non inizializza dati globali o ha altri effetti collaterali quando vengono importati, quindi la memorizzazione nella cache non modifica il comportamento dell'applicazione.
Se la tua applicazione importa un modulo che dipende dal modulo in fase di valutazione per ogni richiesta, deve tenere conto di questo comportamento di memorizzazione nella cache.
Memorizzazione nella cache dei gestori CGI
Puoi indicare ad App Engine di memorizzare nella cache lo script del gestore CGI, oltre ai moduli importati. Se lo script del gestore definisce una funzione denominata
main()
, lo script e il relativo ambiente globale verranno memorizzati nella cache come un
modulo importato. La prima richiesta dello script su un determinato server web
valuta lo script normalmente. Per le richieste successive, App Engine chiama
la funzione main()
nell'ambiente memorizzato nella cache.
Per memorizzare nella cache uno script del gestore, App Engine deve essere in grado di chiamare main()
senza argomenti. Se lo script del gestore non definisce una funzione main()
o se la funzione main()
richiede argomenti (che non hanno valori predefiniti), App Engine carica e valuta l'intero script per ogni richiesta.
Mantenere il codice Python analizzato in memoria consente di risparmiare tempo e ottenere risposte più rapide. La memorizzazione nella cache dell'ambiente globale ha anche altri potenziali utilizzi:
Espressioni regolari compilate. Tutte le espressioni regolari vengono analizzate e archiviate in un formato compilato. Puoi archiviare le espressioni regolari compilate in variabili globali, quindi utilizzare la memorizzazione nella cache delle app per riutilizzare gli oggetti compilati tra le richieste.
Oggetti GqlQuery. La stringa di query GQL viene analizzata durante la creazione dell'oggetto GqlQuery. Il riutilizzo di un oggetto GqlQuery con l'associazione di parametri e il metodo bind() è più veloce della ricostruzione dell'oggetto ogni volta. Puoi archiviare un oggetto GqlQuery con l'associazione di parametri per i valori in una variabile globale, quindi riutilizzarlo associando nuovi valori dei parametri per ogni richiesta.
File di configurazione e di dati. Se la tua applicazione carica e analizza i dati di configurazione da un file, può conservare i dati analizzati in memoria per evitare di dover ricaricare il file a ogni richiesta.
Lo script del gestore deve chiamare main()
quando viene importato. App Engine
prevede che l'importazione dello script chiami main()
, quindi non
lo chiama quando carica il gestore delle richieste per la prima volta su un server.
La memorizzazione nella cache delle app con main()
migliora notevolmente il tempo di risposta del gestore CGI. Lo consigliamo per tutte le applicazioni che utilizzano CGI.
Logging
Il server web App Engine acquisisce tutto ciò che lo script del gestore scrive nel flusso di output standard per la risposta alla richiesta web. Inoltre, acquisisce tutto ciò che lo script del gestore scrive nel flusso di errori standard e lo memorizza come dati di log. A ogni richiesta viene assegnato unrequest_id
, un
identificatore univoco globale basato sull'ora di inizio della richiesta. I dati di log per la tua applicazione possono essere visualizzati nella console Google Cloud utilizzando Cloud Logging.
L'ambiente runtime Python di App Engine include un supporto speciale per il modulo logging della libreria standard Python per comprendere i concetti di logging come i livelli di log ("debug", "info", "warning", "error", "critical").
L'ambiente
L'ambiente di esecuzione imposta automaticamente diverse variabili di ambiente. Puoi impostarne altre inapp.yaml
. Delle variabili impostate automaticamente, alcune sono specifiche
di App Engine, mentre altre fanno parte degli standard WSGI o CGI. Il codice Python
può accedere a queste variabili utilizzando il dizionario os.environ
.
Le seguenti variabili di ambiente sono specifiche di App Engine:
CURRENT_VERSION_ID
: La versione principale e secondaria dell'applicazione attualmente in esecuzione, nel formato "X.Y". Il numero di versione principale ("X") è specificato nel fileapp.yaml
dell'app. Il numero di versione secondaria ("Y") viene impostato automaticamente quando ogni versione dell'app viene caricata su App Engine. Sul server web di sviluppo, la versione secondaria è sempre "1".AUTH_DOMAIN
: il dominio utilizzato per autenticare gli utenti con l'API Users. Le app ospitate su appspot.com hanno unAUTH_DOMAIN
digmail.com
e accettano qualsiasi Account Google. Le app ospitate su un dominio personalizzato hanno unAUTH_DOMAIN
uguale al dominio personalizzato.INSTANCE_ID
: contiene l'ID istanza dell'istanza frontend che gestisce una richiesta. L'ID è una stringa esadecimale (ad esempio,00c61b117c7f7fd0ce9e1325a04b8f0df30deaaf
). Un amministratore che ha eseguito l'accesso può utilizzare l'ID in un URL:https://INSTANCE_ID-dot-VERSION_ID-dot-SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com
. La richiesta verrà indirizzata a quella specifica istanza frontend. Se l'istanza non è in grado di gestire la richiesta, restituisce immediatamente un errore 503.
Le seguenti variabili di ambiente fanno parte degli standard WSGI e CGI, con un comportamento speciale in App Engine:
SERVER_SOFTWARE
: nel server web di sviluppo, questo valore è "Development/X.Y", dove "X.Y" è la versione del runtime. Quando viene eseguito su App Engine, questo valore è "Google App Engine/X.Y.Z".
Le variabili di ambiente aggiuntive vengono impostate in base allo standard WSGI o CGI. Per ulteriori informazioni su queste variabili, consulta lo standard WSGI o lo standard CGI, a seconda dei casi.
Puoi anche impostare le variabili di ambiente nel fileapp.yaml
:
env_variables:
DJANGO_SETTINGS_MODULE: 'myapp.settings'
Il seguente gestore di richieste webapp2 mostra ogni variabile di ambiente visibile all'applicazione nel browser:
ID richiesta
Al momento della richiesta, puoi salvare l'ID richiesta, che è univoco per quella richiesta. L'ID richiesta può essere utilizzato in un secondo momento per cercare i log relativi alla richiesta in Cloud Logging.
Il seguente codice campione mostra come ottenere l'ID richiesta nel contesto di una richiesta:
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
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 le risposte generate dal tuo codice, utilizza la
libreria flask-talisman
.
Gestione del lavoro asincrono in background
Il lavoro in background è qualsiasi lavoro che la tua app esegue per una richiesta dopo aver fornito la risposta HTTP. Evita di eseguire operazioni in background nella tua app e controlla il codice per assicurarti che tutte le operazioni asincrone terminino prima di fornire la risposta.
Per i job a esecuzione prolungata, consigliamo di utilizzare Cloud Tasks. Con Cloud Tasks, le richieste HTTP sono di lunga durata e restituiscono una risposta solo al termine di qualsiasi lavoro asincrono.