ID regione
REGION_ID
è un codice abbreviato assegnato da Google in base alla regione selezionata quando crei l'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 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 come l'applicazione App Engine riceve le richieste e invia le risposte.
Per maggiori dettagli, consulta la documentazione di riferimento su intestazioni di richiesta e risposte.
Se la tua applicazione utilizza i servizi, puoi indirizzare le richieste a un servizio specifico o a una versione specifica di quel servizio. Per ulteriori informazioni sull'addressability del servizio, consulta In che modo vengono instradate le 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.
Quando App Engine riceve una richiesta web per la tua applicazione, invoca il servlet corrispondente all'URL, come descritto nel file web.xml
dell'applicazione nella directory WEB-INF/
.
Supporta le specifiche dell'API Java Servlet 2.5 o 3.1 per fornire i dati della richiesta al servlet e accettare i dati della risposta.
App Engine esegue più istanze della tua applicazione, ognuna con il proprio server web per gestire le richieste. Qualsiasi richiesta può essere inoltrata a qualsiasi istanza, pertanto le richieste consecutive dello stesso utente non vengono necessariamente inviate alla stessa istanza. Il numero di istanze può essere regolato automaticamente in base alle variazioni del traffico.
Per impostazione predefinita, ogni server web elabora una sola richiesta alla volta. Per inviare più richieste a ciascun server web in parallelo, contrassegna la tua applicazione come sicura per i thread aggiungendo un elemento <threadsafe>true</threadsafe>
al file appengine-web.xml
.
Il seguente esempio di classe servlet mostra un semplice messaggio nel browser dell'utente.
Quote e limiti
App Engine alloca automaticamente le risorse alla tua applicazione man mano che il traffico aumenta. Tuttavia, sono previste le seguenti limitazioni:
App Engine riserva la capacità di scalabilità automatica per le applicazioni con una bassa latenza, in cui l'applicazione risponde alle richieste in meno di un secondo.
Le applicazioni che richiedono un'elevata elaborazione della CPU potrebbero anche presentare 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 arrivo 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).
Sia le richieste HTTP che quelle HTTPS (sicure) vengono conteggiate ai fini dei limiti di Richieste, Larghezza di banda in entrata (fatturabile) e Larghezza di banda in uscita (fatturabile). La pagina dei dettagli delle quote della console Google Cloud riporta 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 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 in totale 1000 per directory |
Dimensione massima di un file dell'applicazione | 32 megabyte |
Dimensione massima di un file statico | 32 megabyte |
Dimensioni totali massime di tutti i file di applicazioni e statici | I primi 1 GB sono gratuiti 0,026$ per GB al mese dopo i primi 1 GB |
Timeout della richiesta in attesa | 10 secondi |
Dimensione massima di un singolo campo dell'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 tradotte in richieste HTTP/1.1 quando vengono inoltrate al server dell'applicazione.
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 (Errore interno del server). Questa limitazione non si applica alle risposte che forniscono dati provenienti dall'archivio BLOB precedente o da Cloud Storage.
Il limite di intestazione di risposta è 8 KB per i 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 arrivo include le intestazioni HTTP inviate dal client. Per motivi di sicurezza, alcune intestazioni vengono sottoposte a sanificazione o modificate da proxy intermedi prima di raggiungere l'applicazione.
Per ulteriori informazioni, consulta la sezione Informazioni di riferimento sulle intestazioni delle richieste.
Gestione dei timeout delle richieste
App Engine è ottimizzato per le applicazioni con richieste di breve durata, tipicamente quelle che richiedono alcune centinaia di millisecondi. Un'app efficiente risponde rapidamente alla maggior parte delle richieste. Un'app che non lo fa non avrà una buona scalabilità con l'infrastruttura di App Engine. Per garantire questo livello di prestazioni, esiste 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 delle richieste. L'ambiente di runtime Java interrompe il servlet lanciando uncom.google.apphosting.api.DeadlineExceededException
.
Se non è presente un gestore delle richieste per rilevare questa eccezione, l'ambiente di runtime restituirà al client un errore del server HTTP 500.
Se esiste un gestore delle richieste e viene rilevato DeadlineExceededException
,
l'ambiente di runtime concede al gestore delle richieste il tempo (meno di un secondo)
per preparare una risposta personalizzata. Se il gestore delle richieste impiega più di un secondo
dopo aver sollevato l'eccezione per preparare una risposta personalizzata, verrà sollevato un
HardDeadlineExceededError
.
Sia DeadlineExceededExceptions
sia HardDeadlineExceededErrors
forzano la terminazione della richiesta e arrestano l'istanza.
Per scoprire quanto tempo rimane prima della scadenza, l'applicazione può importare com.google.apphosting.api.ApiProxy
e chiamare ApiProxy.getCurrentEnvironment().getRemainingMillis()
.
Questo è utile se l'applicazione prevede di iniziare un lavoro che potrebbe richiedere troppo tempo. Se sai che l'elaborazione di un'unità di lavoro richiede cinque secondi, ma getRemainingMillis()
restituisce un tempo inferiore, non ha senso avviare l'unità di lavoro.
Risposte
App Engine chiama il servlet con un oggetto request e un oggetto risposta, quindi attende che il servlet completi l'oggetto risposta e ritorni. Quando il servlet ritorna, i dati dell'oggetto di risposta vengono inviati all'utente.Esistono limiti di dimensione che si applicano alla risposta generata e la risposta può essere modificata prima di essere restituita al client.
Per ulteriori informazioni, consulta la sezione Documentazione di riferimento per le risposte alle richieste.Risposte dinamiche
App Engine non supporta le risposte in streaming 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 sopra e inviati come singola risposta HTTP.
Compressione delle risposte
App Engine fa del suo meglio per pubblicare contenuti compressi (con gzip) per i client che li supportano. Per determinare se i contenuti devono essere compressi, App Engine esegue le seguenti operazioni quando riceve una richiesta:Verifica se il client può ricevere in modo affidabile le risposte compresse visualizzando entrambe le intestazioni
Accept-Encoding
eUser-Agent
nella richiesta. Questo approccio evita alcuni bug noti relativi ai contenuti compressi con gzip nei browser più diffusi.Verifica se la compressione dei contenuti è appropriata visualizzando l'intestazione
Content-Type
che hai configurato per il gestore della risposta. In generale, la compressione è appropriata per i tipi di contenuti basati su testo e non per i 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 di 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 directory e file statici di App Engine. A seconda di una serie di fattori, ad esempio il tipo di dati della risposta memorizzati nella cache per primo, le intestazioni
Vary
che hai specificato 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 server proxy intermediari per la memorizzazione nella cache memorizzeranno nella cache le risposte della tua app come indicato dalle intestazioni di memorizzazione nella cache standard specificate nella risposta. Puoi specificare queste intestazioni di risposta tramite il tuo framework, direttamente nel codice o tramite gli handler di directory e file statici di App Engine.
In Google Frontend, la chiave della cache è l'URL completo della richiesta.
Memorizzazione nella cache dei contenuti statici
Per assicurarti che i clienti ricevano sempre contenuti statici aggiornati non appena vengono pubblicati, ti consigliamo di pubblicare contenuti statici da directory con versioni, ad esempio css/v1/styles.css
. Il Frontend di Google non convalida
la cache (controlla la presenza di contenuti aggiornati) fino alla scadenza della cache. Anche dopo la scadenza della cache, questa non verrà aggiornata finché i contenuti dell'URL della richiesta non cambieranno.
Le seguenti intestazioni di risposta che puoi
impostare in appengine-web.xml
influiscono su 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. Potrebbe anche essere memorizzato nella cache dal frontend di Google, a meno che non specifichi un'istruzioneCache-Control
private
ono-store
. Se non imposti questo header inappengine-web.xml
, App Engine lo aggiunge automaticamente per tutte le risposte gestite da un gestore di directory o file 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 agli intestazioni inviati nella richiesta, imposta uno o più dei seguenti valori nell'intestazione di rispostaVary
:Accept
,Accept-Encoding
,Origin
oX-Origin
A causa della potenziale alta cardinalità, i dati non verranno memorizzati nella cache per altri valori
Vary
.Ad esempio:
Specifica la seguente intestazione di risposta:
Vary: Accept-Encoding
La tua app riceve una richiesta che contiene l'intestazione
Accept-Encoding: gzip
. App Engine restituisce una risposta compressa e il frontend di Google memorizza nella cache la versione compressa con gzip dei dati della risposta. Tutte le richieste successive per questo URL che contengono l'intestazioneAccept-Encoding: gzip
riceveranno i dati compressi con gzip dalla cache fino a quando 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 della 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 utilizza per tutte le richieste, indipendentemente dalle intestazioni nella richiesta. Ad esempio:- Non specifichi l'intestazione della risposta
Vary: Accept-Encoding
. - Una richiesta contiene l'intestazione
Accept-Encoding: gzip
e la versione compressa con gzip 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.
Le intestazioni nella richiesta influiscono anche sulla memorizzazione nella cache:
- Se la richiesta contiene un'intestazione
Authorization
, i contenuti non verranno memorizzati nella cache dal frontend di Google.
Scadenza della cache
Per impostazione predefinita, le intestazioni di memorizzazione nella cache aggiunte ai gestori di directory e file statici di App Engine alle risposte ordinano ai client e ai proxy web, come il frontend di Google, di far scadere la cache dopo 10 minuti.
Dopo che un file è stato trasmesso con una determinata data e ora di scadenza, in genere non è possibile rimuoverlo dalle cache del proxy web, anche se l'utente svuota la cache del proprio browser. Il nuovo deployment di una nuova versione dell'app non reimposta le cache. Pertanto, se prevedi di modificare un file statico, deve avere un breve periodo di scadenza (meno di un'ora). Nella maggior parte dei casi, il valore predefinito di 10 minuti per la data e l'ora di scadenza è appropriato.
Puoi modificare la scadenza predefinita per tutti i gestori di file e directory statici
specificando l'elemento
static-files
nel file appengine-web.xml
.
Logging
L'applicazione può scrivere informazioni nei log dell'applicazione utilizzando java.util.logging.Logger. I dati dei log per l'applicazione possono essere visualizzati nella console Google Cloud utilizzando Cloud Logging. A ogni richiesta registrata viene assegnato un ID richiesta, un identificatore univoco globale basato sull'ora di inizio della richiesta. La console Google Cloud è in grado di riconoscere i livelli di log della classeLogger
e di visualizzare in modo interattivo i messaggi a diversi livelli.
Tutto ciò che il servlet scrive nello stream di output standard (System.out
) e nello stream di errori standard (System.err
) viene acquisito da App Engine e registrato nei log dell'applicazione. Le righe scritte nello stream di output standard vengono registrate a livello di "INFO", mentre le righe scritte nello stream di errori standard vengono registrate a livello di "AVVERTENZA". È possibile utilizzare qualsiasi framework di logging (ad esempio log4j) che registra gli eventi negli stream di output o di errore. Tuttavia, per un controllo più granulare della visualizzazione del livello di log nella console Google Cloud, il framework di logging deve utilizzare un adattatore java.util.logging
.
L'SDK Java di App Engine include un file modello logging.properties
nella directory appengine-java-sdk/config/user/
. Per utilizzarlo, copia il file nella directory WEB-INF/classes
(o in un'altra posizione nel file WAR), quindi la proprietà di sistema java.util.logging.config.file
in "WEB-INF/logging.properties"
(o in qualsiasi percorso scelto in base alla radice dell'applicazione). Puoi impostare le proprietà di sistema nel
file appengine-web.xml
come segue:
Il servlet registra i messaggi utilizzando il livello di log INFO
(utilizzando log.info()
). Il livello di log predefinito è WARNING
, che elimina i messaggi INFO
dall'output. Per modificare il livello di log, modifica il file logging.properties
.
L'ambiente
Tutte le proprietà di sistema e le variabili di ambiente sono private per la tua applicazione. L'impostazione di una proprietà di sistema influisce solo sulla visualizzazione di quella proprietà da parte dell'applicazione, e non sulla visualizzazione della JVM.Puoi impostare le proprietà di sistema e le variabili di ambiente per la tua app nel descrittore di deployment.
App Engine imposta diverse proprietà di sistema che identificano l'ambiente di runtime:
com.google.appengine.runtime.environment
è"Production"
quando viene eseguito su App Engine e"Development"
quando viene eseguito nel server di sviluppo.Oltre a utilizzare
System.getProperty()
, puoi accedere alle proprietà del sistema utilizzando la nostra API sicura per i tipi. Ad esempio:if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) { // The app is running on App Engine... }
com.google.appengine.runtime.version
è l'ID versione dell'ambiente di runtime, ad esempio"1.3.0"
. Puoi ottenere la versione richiamando quanto segue:String version = SystemProperty.version.get();
com.google.appengine.application.id
è l'ID dell'applicazione. Puoi ottenere l'ID richiamando quanto segue:String ID = SystemProperty.applicationId.get();
com.google.appengine.application.version
è la versione principale e secondaria del servizio dell'applicazione attualmente in esecuzione, ad esempio "X.Y". Il numero di versione principale ("X") è specificato nel fileappengine-web.xml
del servizio. Il numero della versione minore ("Y") viene impostato automaticamente quando ogni versione dell'app viene caricata su App Engine. Puoi ottenere l'ID richiamando quanto segue:String ID = SystemProperty.applicationVersion.get();
Sul server web di sviluppo, la versione principale restituita è sempre la versione del servizio predefinito e la versione secondaria è sempre "1".
App Engine imposta inoltre le seguenti proprietà di sistema quando inizializza la JVM su un server app:
file.separator
path.separator
line.separator
java.version
java.vendor
java.vendor.url
java.class.version
java.specification.version
java.specification.vendor
java.specification.name
java.vm.vendor
java.vm.name
java.vm.specification.version
java.vm.specification.vendor
java.vm.specification.name
user.dir
ID istanza
Puoi recuperare l'ID dell'istanza che gestisce una richiesta utilizzando questo codice:
com.google.apphosting.api.ApiProxy.getCurrentEnvironment().getAttributes().get("com.google.appengine.instance.id")
Nell'ambiente di produzione, 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 quell'istanza specifica. Se l'istanza non può gestire la richiesta, restituisce immediatamente un codice 503.
ID richiesta
Al momento della richiesta, puoi salvare l'ID richiesta, che è univoco per la richiesta. L'ID richiesta può essere utilizzato in un secondo momento per correlare una richiesta ai relativi log.
Il seguente codice mostra come ottenere l'ID richiesta nel contesto di una richiesta:
com.google.apphosting.api.ApiProxy.getCurrentEnvironment().getAttributes().get("com.google.appengine.runtime.request_log_id")
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
La maggior parte dei framework per app e dei server web supporta l'impostazione di questo intestazione per le risposte generate dal codice. Per informazioni sull'intestazione Strict-Transport-Security
in Spring Boot, consulta HTTP Strict Transport Security (HSTS).
Gestione del lavoro in background asincrono
Il lavoro in background è qualsiasi lavoro eseguito dalla tua app per una richiesta dopo che hai fornito la risposta HTTP. Evita di eseguire operazioni in background nella tua app e controlla il codice per assicurarti che tutte le operazioni asincrone vengano completate prima di inviare la risposta.
Per i job di lunga durata, 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.