ID regione
REGION_ID
è un codice abbreviato assegnato da Google in base alla regione selezionata al momento della creazione dell'app. Non corrisponde a un paese o a una provincia, anche se alcuni ID regione possono apparire 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 regione è facoltativo nell'URL.
Scopri di più sugli ID regione.
Questo documento descrive come l'applicazione App Engine riceve richieste e invia risposte.
Per maggiori dettagli, consulta l'articolo Riferimento per 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 di quel servizio. Per maggiori informazioni sull'indirizzabilità dei servizi, consulta Modalità di routing delle richieste.
Gestione delle richieste
La tua 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, richiama il servlet che corrisponde 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 di risposta.
App Engine esegue più istanze dell'applicazione, ognuna 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. Il numero di istanze può essere regolato automaticamente in base alle variazioni del traffico.
Per impostazione predefinita, ciascun server web elabora una sola richiesta alla volta. Per inviare
più richieste in parallelo a ogni server web, contrassegna la tua applicazione come
threadsafe aggiungendo un elemento <threadsafe>true</threadsafe>
al file appengine-web.xml
.
La classe servlet di esempio riportata di seguito mostra un semplice messaggio sul browser dell'utente.
Quote e limiti
App Engine alloca automaticamente le risorse alla tua applicazione man mano che il traffico aumenta. Tuttavia, ciò è vincolato dalle seguenti limitazioni:
App Engine riserva una capacità di scalabilità automatica per le applicazioni a bassa latenza, in cui l'applicazione risponde alle richieste in meno di un secondo.
Le applicazioni molto legate alla CPU possono 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 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).
Entrambe le richieste HTTP e 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 della console Google Cloud segnala anche le Richieste sicure, la 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'uso dei gestori delle richieste:
Limite | Quantità |
---|---|
Dimensioni richiesta | 32 megabyte |
Dimensione della risposta | 32 megabyte |
Timeout richiesta | Dipende dal tipo di scalabilità utilizzato dall'app |
Numero totale massimo di file (file di app e file statici) | 10.000 in totale 1000 per directory |
Dimensione massima 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 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 saranno tradotte in richieste HTTP/1.1 quando inoltrate al server delle applicazioni.
Limiti di risposta
Le risposte dinamiche hanno un limite di 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 errore interno del server 500. 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 della 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 controllate o modificate da proxy intermedi prima che raggiungano l'applicazione.
Per saperne di più, consulta la sezione Riferimento alle intestazioni delle richieste.
Gestione dei timeout delle richieste
App Engine è ottimizzato per le applicazioni con richieste di breve durata, in genere quelle che richiedono alcune centinaia di millisecondi. Un'app efficiente risponde rapidamente alla maggior parte delle richieste. un'app che non scala bene con l'infrastruttura di App Engine. Per garantire questo livello di prestazioni, è previsto un timeout della richiesta massimo imposto dal sistema tramite 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 generando uncom.google.apphosting.api.DeadlineExceededException
.
Se non esiste un gestore delle richieste in grado di rilevare questa eccezione, l'ambiente di runtime restituirà un errore del server HTTP 500 al client.
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à generato un valore HardDeadlineExceededError
.
Sia DeadlineExceededExceptions
che HardDeadlineExceededErrors
forzeranno la chiusura della richiesta e arrestano l'istanza.
Per sapere 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 avviare un'attività che potrebbe richiedere troppo tempo. Se sai che l'elaborazione di un'unità di lavoro richiede cinque secondi, ma getRemainingMillis()
restituisce meno tempo, è inutile iniziare quell'unità di lavoro.
Risposte
App Engine chiama il servlet con un oggetto request e un oggetto risposta, quindi attende che il servlet compili l'oggetto risposta e restituisca il valore. Quando il servlet viene restituito, i dati relativi all'oggetto risposta vengono inviati all'utente.Alla risposta generata si applicano limiti di dimensioni e la risposta può essere modificata prima di essere restituita al client.
Per saperne di più, consulta l'articolo Informazioni sulle 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 della richiesta. Tutti i dati provenienti dal codice vengono raccolti come descritto in precedenza e inviati come singola risposta HTTP.
Compressione delle risposte
App Engine fa del suo meglio per distribuire contenuti compressi (gzip) ai client che li 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 entrambe le intestazioni
Accept-Encoding
eUser-Agent
nella richiesta. Questo approccio evita alcuni bug noti con contenuti compressi con gzip nei browser più diffusi.Conferma se la compressione dei contenuti è appropriata visualizzando l'intestazione
Content-Type
che hai configurato per il gestore delle risposte. 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 di 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 comprime i dati della risposta.Google Frontend memorizza nella cache le risposte provenienti dai gestori di directory e file statici di App Engine. A seconda di una serie di fattori, come il tipo di dati di risposta che vengono memorizzati per primi nella cache, le intestazioni
Vary
che hai specificato 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 Memorizzazione nella cache delle risposte.
Memorizzazione nella cache delle risposte
Il frontend Google e, potenzialmente, il browser dell'utente e altri server proxy intermedi con memorizzazione nella cache, memorizzeranno nella cache le risposte della tua app come indicato dalle intestazioni standard di memorizzazione nella cache specificate nella risposta. Puoi specificare queste intestazioni di risposta tramite il framework, direttamente nel codice o tramite i gestori di file statici e directory di App Engine.
Nel frontend Google, la chiave cache è l'URL completo della richiesta.
Memorizzazione nella cache dei contenuti statici
Per fare in modo che i client ricevano sempre contenuti statici aggiornati non appena vengono pubblicati, ti consigliamo di pubblicare contenuti statici da directory sottoposte a controllo delle versioni, ad esempio css/v1/styles.css
. Google Frontend non convalida la cache (verifica la presenza di contenuti aggiornati) fino alla scadenza. Anche dopo la scadenza, questa non verrà aggiornata finché non vengono modificati i contenuti dell'URL di richiesta.
Le seguenti intestazioni di risposta che puoi
impostare
appengine-web.xml
influiscono su come e quando il Google Frontend memorizza i contenuti nella cache:
Cache-Control
deve essere impostato supublic
affinché il frontend Google possa memorizzare i contenuti nella cache; può anche essere memorizzato nella cache dal frontend Google, a meno che non specifichi un'istruzioneCache-Control
private
ono-store
. Se non imposti questa intestazione inappengine-web.xml
, App Engine la aggiunge automaticamente per tutte le risposte gestite da un gestore di directory o file statico. Per scoprire di più, consulta la sezione Intestazioni aggiunte o sostituite.Vary
: per fare in modo che la cache restituisca 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 del potenziale di una cardinalità elevata, i dati non verranno memorizzati nella cache per altri valori
Vary
.Ad esempio:
Specifica la seguente intestazione della risposta:
Vary: Accept-Encoding
L'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 con gzip dei dati della risposta. Tutte le richieste successive per questo URL che contengono l'intestazioneAccept-Encoding: gzip
riceveranno i dati compressi dalla cache fino a quando la cache non verrà 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 delle risposte. Tutte le richieste successive per questo URL che non contengono l'intestazioneAccept-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, a prescindere dalle intestazioni della richiesta. Ad esempio:- Non devi specificare l'intestazione della risposta
Vary: Accept-Encoding
. - Una richiesta contiene l'intestazione
Accept-Encoding: gzip
e la versione compressa con gzip dei dati della 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 della risposta, la risposta verrà compressa con gzip anche se il client ha richiesto dati non compressi.
Anche le intestazioni nella 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 di file statici e di directory 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 viene trasmesso con un determinato orario di scadenza, generalmente non è possibile svuotarlo dalle 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 pianifichi di modificare un file statico, la scadenza deve essere breve (meno di un'ora). Nella maggior parte dei casi, la scadenza predefinita è di 10 minuti.
Puoi modificare la scadenza predefinita per tutti i gestori di directory e file statici
specificando l'elemento
static-files
nel
file appengine-web.xml
.
Logging
La tua applicazione può scrivere informazioni nei log dell'applicazione utilizzando java.util.logging.Logger. I dati di log per la tua 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 può riconoscere i livelli di log della classeLogger
e visualizzare in modo interattivo i messaggi su diversi livelli.
Tutto ciò che il servlet scrive nel flusso di output standard (System.out
) e nel flusso di errori standard (System.err
) viene acquisito da App Engine e registrato nei log dell'applicazione. Le righe scritte nel flusso di output standard vengono registrate al livello "INFO", mentre le righe scritte nel flusso di errori standard vengono registrate al livello "WARNING". Qualsiasi framework di logging (come log4j) che registri i flussi di output o di errore funzionerà. Tuttavia, per un controllo più granulare della visualizzazione a 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 modello di file logging.properties
, nella directory appengine-java-sdk/config/user/
. Per utilizzarlo, copia il file nella tua directory WEB-INF/classes
(o in un altro punto della WAR), quindi la proprietà di sistema java.util.logging.config.file
in "WEB-INF/logging.properties"
(o qualsiasi percorso tu scelga, relativamente 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 cambiare 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 tale proprietà da parte dell'applicazione e non su quella 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 in App Engine e"Development"
quando viene eseguito nel server di sviluppo.Oltre a utilizzare
System.getProperty()
, puoi accedere alle proprietà di sistema utilizzando la nostra API type-safe. 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, come"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 di versione secondaria ("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 predefinita del servizio, mentre la versione secondaria è sempre "1".
Quando inizializza la JVM su un server app, App Engine imposta anche le seguenti proprietà di sistema:
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à instradata
all'istanza specifica. Se l'istanza non riesce a gestire la richiesta, restituisce un errore immediato 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
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, aggiungila ai gestori di file statici e directory dell'app.
La maggior parte dei framework di app e dei server web supporta l'impostazione di questa intestazione
per le risposte generate dal tuo codice. Per informazioni sull'intestazione Strict-Transport-Security
in Spring Boot, consulta HTTP Strict Transport Security (HSTS).
Gestione del lavoro in background asincrono
Per lavoro in background si intende qualsiasi operazione eseguita dalla tua app per una richiesta dopo l'invio della risposta HTTP. Evita di eseguire operazioni in background nell'app ed esamina il codice per assicurarti che tutte le operazioni asincrone vengano completate prima di consegnare la risposta.
Per i job a lunga esecuzione, consigliamo di utilizzare Cloud Tasks. Con Cloud Tasks, le richieste HTTP durano a lungo e restituiscono una risposta solo al termine di qualsiasi lavoro asincrono.