In molti casi, la latenza elevata nell'applicazione comporterà inevitabilmente errori del server 5xx. È quindi opportuno seguire una serie simile di procedure di risoluzione dei problemi, passaggi per restringere la causa principale dei picchi di errore e di latenza, dato che le cause potrebbero essere le stesse.
Definisci l'ambito del problema
Innanzitutto, definisci l'ambito del problema nel modo più preciso possibile raccogliendo informazioni pertinenti. Di seguito sono riportati alcuni suggerimenti di informazioni che potrebbero essere pertinenti.
- Quali ID, servizi e versioni delle applicazioni sono interessati?
- Quali endpoint specifici dell'app sono interessati?
- Il problema ha interessato tutti i clienti a livello globale o un sottoinsieme specifico di clienti?
- Quali sono l'ora di inizio e di fine dell'incidente? Devi specificare il fuso orario.
- Quali errori specifici hai riscontrato?
- Qual è il delta della latenza osservato, che di solito viene specificato come di aumento a un percentile specifico? Ad esempio, la latenza è aumentata di 2 di secondi al 90° percentile.
- Come hai misurato la latenza? In particolare, è stato misurato o è visibile in Cloud Logging e/o in Cloud Monitoring di latenza fornita dall'infrastruttura di gestione di App Engine?
- Quali sono le dipendenze della tua applicazione e si sono verificati incidenti?
- Di recente hai apportato modifiche al codice, alla configurazione o al carico di lavoro che potrebbero aver attivato questo problema?
Un'applicazione potrebbe avere un proprio monitoraggio e un proprio logging personalizzati che puoi utilizzare per restringere ulteriormente l'ambito del problema oltre i suggerimenti precedenti. Definire l'ambito del problema ti aiuterà a individuare la probabile causa principale e a determinare i passaggi successivi per la risoluzione dei problemi.
Determinare cosa non è riuscito
Successivamente, determina quale componente del percorso di richiesta ha maggiori probabilità di essere causando la latenza o gli errori. I componenti principali nel percorso della richiesta sono:
Cliente -> Internet -> Google Front End (GFE) -> Infrastruttura di gestione App Engine -> Istanza di applicazione
Se le informazioni raccolte nel passaggio 1 non indicano la fonte dell'errore, in genere devi iniziare esaminando lo stato e le prestazioni delle istanze dell'applicazione.
Un modo per determinare se il problema risiede o meno nella tua applicazione è esaminare i log delle richieste di App Engine: se vedi il codice di stato HTTP o una latenza elevata nei log, in genere significa che nell'istanza che esegue la tua applicazione.
Esiste uno scenario in cui errori e latenza elevati nei log delle richieste potrebbe non essere causato dall'istanza dell'applicazione stessa: se il numero di istanze della tua applicazione non è stato sottoposto a scale up per soddisfare i livelli di traffico, la tua le istanze gestite possono essere sovraccaricate, con conseguenti errori elevati e latenza.
Se in Cloud Monitoring noti errori o latenze elevati, in genere puoi concludere che il problema si trova a monte del bilanciatore del carico, che registra le metriche di App Engine. Nella maggior parte dei casi, questo indica un problema nelle istanze dell'applicazione.
Tuttavia, se noti una latenza elevata o errori nelle metriche di monitoraggio, ma non nei log delle richieste, potrebbero essere necessarie ulteriori indagini. Potrebbe indicare un errore nel livello di bilanciamento del carico o che le istanze stanno riscontrando un errore così grave che il bilanciatore del carico non può indirizzare le richieste. Per distinguere tra questi casi, puoi esaminare i log delle richieste poco prima dell'inizio dell'incidente. Se i log delle richieste mostrano una latenza in aumento appena prima dell'errore, significa che le istanze di applicazione stesse stavano iniziando a non funzionare prima che il bilanciatore del carico smetta di inoltrare le richieste.
Scenari che potrebbero causare incidenti
Di seguito sono riportati alcuni scenari riscontrati dagli utenti.
Client
Mappare un indirizzo IP del client a una regione geografica
Google risolve il nome host dell'applicazione App Engine nel GFE più vicino al client in base all'indirizzo IP del client utilizzato nella ricerca DNS. Se il resolver DNS del client non utilizza EDNS0 protocollo, le richieste del client potrebbero non essere indirizzate al GFE più vicino.
Internet
Connettività a internet scadente
Esegui il seguente comando sul client per determinare se il problema è la scarsa connettività a internet.
$ curl -s -o /dev/null -w '%{time_connect}\n' <hostname>
Il valore di time_connect
rappresenta in genere la latenza della connessione del client all'endpoint di frontend di Google più vicino. Se
questa connessione è lenta, puoi risolvere ulteriori problemi utilizzando traceroute
per
determinare quale hop sulla rete causa il ritardo.
Puoi eseguire test da client in località geografiche diverse. Le richieste verranno instradate automaticamente al data center Google più vicino, che varierà in base alla posizione del cliente.
Client con larghezza di banda ridotta
L'applicazione potrebbe rispondere velocemente, ma la risposta potrebbe essere rallentata. da colli di bottiglia di rete che fanno sì che l'infrastruttura di gestione di App Engine non di inviare pacchetti attraverso la rete con la massima rapidità.
Google Front End (GFE)
Blocco della prima riga HTTP/2
I client HTTP/2 che inviano più richieste in parallelo potrebbero registrare una latenza elevata a causa di un blocco "head of line" presso il GFE. La soluzione migliore è per i clienti eseguire l'upgrade per utilizzare QUIC.
Terminazione SSL per domini personalizzati
GFE termina la connessione SSL. È richiesto un hop aggiuntivo per SSL risoluzione se utilizzi un dominio personalizzato, anziché un appspot.com dominio. Ciò potrebbe aggiungere latenza per le applicazioni in esecuzione in regioni.
Infrastruttura di gestione di App Engine
Incidente a livello di servizio
Google pubblicherà i dettagli di un servizio grave a livello di servizio all'indirizzo https://status.cloud.google.com/. Tieni presente che Google esegue le implementazioni gradualmente, pertanto è improbabile che un incidente a livello di servizio influisca su tutte le tue istanze contemporaneamente.
Scalabilità automatica
Aumentare troppo velocemente il traffico
La scalabilità automatica di App Engine potrebbe non scalare le tue istanze alla stessa velocità del traffico aumenta, causando un sovraccarico temporaneo. In genere, si verifica quando il traffico non viene generato in modo organico dagli utenti finali, ma da un programma per computer. Il modo migliore per risolvere il problema è limitare il sistema che genera traffico.
Picchi di traffico
I picchi di traffico possono causare latenza elevata nei casi in cui un modello con scalabilità automatica l'applicazione deve fare lo scale up più rapidamente del possibile senza influire una latenza di pochi millisecondi. Il traffico degli utenti finali di solito non causa picchi di traffico frequenti. Se vedi questo messaggio, devi esaminare la causa degli picchi di traffico. Se un sistema batch è in esecuzione a intervalli, potresti essere in grado il traffico o utilizzare impostazioni di scalabilità diverse.
Impostazioni del gestore della scalabilità automatica
Il gestore della scalabilità automatica può essere configurato in base alle caratteristiche di scalabilità dei tuoi un'applicazione. Questi parametri di scala possono diventare non ottimali durante diversi scenari.
Le applicazioni nell'ambiente flessibile di App Engine scalano in base all'utilizzo della CPU. Ma l'applicazione potrebbe essere vincolata I/O durante un incidente con conseguente sovraccarico le istanze con un numero elevato di richieste perché la scalabilità basata sulla CPU che si verificano.
Scalabilità dell'ambiente standard di App Engine
impostazioni potrebbero
causare latenza se il modello è impostato in modo troppo aggressivo. Se vedi risposte del server con
il codice di stato 500
e il messaggio Request was aborted after waiting too long to
attempt to service your
request
nei log, significa che la richiesta è scaduta nella coda in attesa.
in attesa di un'istanza inattiva.
Non utilizzare il scaling manuale dell'ambiente standard di App Engine se la tua app serve traffico utente finale. La scalabilità manuale è preferibile per carichi di lavoro come le code di attività. Potresti notare un aumento del tempo in attesa con il ridimensionamento manuale anche se hai eseguito il provisioning di istanze sufficienti.
Non utilizzare la scalabilità di base dell'ambiente standard di App Engine per le applicazioni sensibili alla latenza. Questo tipo di scalabilità è progettato per ridurre al minimo a scapito della latenza.
Le impostazioni di scalabilità predefinite dell'ambiente standard di App Engine forniscono per la maggior parte delle applicazioni. Se continui a visualizzare richieste con tempi di attesa elevati, puoi specificare un numero minimo di istanze. Se modifichi le impostazioni di scalabilità riducendo al minimo le istanze inattive, c'è il rischio di vedere i picchi di latenza se il carico aumenta improvvisamente.
Ti consigliamo di usare il benchmark prestazioni con le impostazioni di scalabilità predefinite, quindi esegui un nuovo benchmark dopo ogni modifica queste impostazioni.
Deployment
Una latenza elevata poco dopo un deployment indica che non sono abbia fatto uno scale up sufficiente prima di eseguire la migrazione del traffico. Le istanze più recenti potrebbero non aver preriscaldato le cache locali e quindi potrebbero essere più lente delle istanze precedenti.
Per evitare picchi di latenza, non eseguire il deployment di un'app di App Engine utilizzando la stessa versione nome come versione esistente dell'app. Se riutilizzi un nome versione esistente, non potrai eseguire lentamente la migrazione del traffico alla nuova versione. Le richieste possono essere perché ogni istanza viene riavviata entro un breve periodo nel tempo. Dovrai anche eseguire nuovamente il deployment se vuoi ripristinare la versione precedente.
Istanza dell'applicazione
Codice dell'applicazione
Il debug di problemi nel codice dell'applicazione può essere molto difficile, in particolare sono intermittenti o non si riproducono facilmente. Per aiutarti a diagnosticare i problemi, ti consigliamo di eseguire l'instrumentazione dell'applicazione utilizzando il logging, il monitoraggio e il tracciamento. Puoi provare a utilizzare Cloud Profiler per diagnosticare i problemi. Guarda questo esempio di diagnosticare la richiesta di caricamento latenza utilizzando Cloud Trace per caricare informazioni sulla tempistica aggiuntive per ogni richiesta.
Puoi anche provare a riprodurre il problema in un ambiente di sviluppo locale, che potrebbe consentirti di eseguire strumenti di debug specifici per la lingua che potrebbero non essere possibili in App Engine.
Se esegui l'applicazione nell'ambiente flessibile App Engine, puoi accedere tramite SSH a un'istanza ed eseguire un dump del thread per visualizzare lo stato attuale dell'applicazione. Puoi provare a riprodurre il problema in un test di carico o eseguendo l'app in locale. Puoi aumentare la dimensione dell'istanza per vedere se il problema si risolve problema. Ad esempio, un aumento della RAM può risolvere problemi per le applicazioni che ritardi dovuti alla garbage collection.
Per comprendere meglio in che modo l'app non funziona e quali colli di bottiglia si verificano, puoi caricare e testare l'applicazione fino all'errore. Imposta un numero massimo di istanze, quindi aumenta gradualmente il carico fino a quando l'applicazione non si arresta in modo anomalo.
Se il problema di latenza è correlato al deployment di una nuova versione dell'applicazione, puoi eseguire il rollback per determinare se ha causato l'incidente. Se esegui il deployment continuo, potresti avere e i deployment frequenti, quindi è difficile determinare ha causato l'incidente in base al momento di insorgenza.
L'applicazione può archiviare le impostazioni di configurazione all'interno di Datastore altrove. Ti sarà utile creare una sequenza temporale per la configurazione. modifiche per determinare se una di queste è in linea con l'insorgenza di livelli elevati una latenza di pochi millisecondi.
Modifica del carico di lavoro
Una modifica del carico di lavoro potrebbe causare una latenza elevata. Alcune metriche di monitoraggio che potrebbero indicano che il carico di lavoro modificato include QPS nonché utilizzo o latenza dell'API. Puoi anche verificare la presenza di modifiche nelle dimensioni di richieste e risposte.
Errori del controllo di integrità
Il bilanciatore del carico dell'ambiente flessibile di App Engine interromperà il routing delle richieste a che non superano i controlli di integrità. Questo potrebbe aumentare il carico su altre istanze, che potrebbero causare un errore a cascata. Log Nginx dell'ambiente flessibile di App Engine le istanze che non superano i controlli di integrità. Analizza i log e il monitoraggio per determinare il motivo per cui l'istanza non è più integra o configura i controlli di integrità in modo che siano meno sensibili agli errori transitori. Tieni presente che ci sarà un breve ritardo prima che il bilanciatore del carico interrompa il routing del traffico verso un'istanza non integra. Questo ritardo potrebbe causare un picco di errori se il bilanciatore del carico non può riprovare richieste.
L'ambiente standard di App Engine non utilizza i controlli di integrità.
Pressione di memoria
Se il monitoraggio mostra un modello a dente di sega nell'utilizzo della memoria o un calo dell'utilizzo della memoria correlato ai deployment, allora potrebbero causata da una perdita di memoria. Una perdita di memoria potrebbe causare una raccolta dei rifiuti frequente che comporta un aumento della latenza. Il provisioning di istanze più grandi con più memoria potrebbe risolvere il problema se non riesci a risalire facilmente a un problema nel codice.
Perdita di risorse
Se un'istanza della tua applicazione mostra una latenza in aumento correlata all'età dell'istanza, è possibile che si verifichi una perdita di risorse che causa problemi di prestazioni. In questo tipo di problema, noterai anche cali di latenza subito dopo un deployment. Ad esempio, una struttura di dati che diventa più lenta nel tempo a causa di un utilizzo più elevato della CPU potrebbe causare un rallentamento di qualsiasi carico di lavoro vincolato alla CPU.
Ottimizzazione del codice
Ecco alcuni modi in cui puoi ottimizzare il codice su App Engine per ridurre la latenza:
Lavoro offline: utilizza Cloud Tasks in modo che le richieste degli utenti non si blocchino in attesa del completamento di un'attività, ad esempio l'invio di email.
Chiamate API asincrone: assicurati che il codice non sia bloccato in attesa del completamento di una chiamata API. Librerie come ndb offrono il supporto integrato per questo.
Chiamate API batch: la versione batch delle chiamate API è in genere più veloce dell'invio di singole chiamate.
Denormalizza i modelli di dati: riduci la latenza delle chiamate al livello di persistenza dei dati denormalizzando i modelli di dati.
Dipendenze
Puoi monitorare le dipendenze dell'applicazione per rilevare i picchi di latenza sono correlati a un errore delle dipendenze.
Un aumento della latenza per una dipendenza può essere causato da una modifica del carico di lavoro e un aumento del traffico.
Dipendenza non scalabile
Se la dipendenza non viene scalata con la scalabilità del numero di istanze App Engine allora la dipendenza potrebbe sovraccaricarsi quando il traffico aumenta. Esempio di una dipendenza che potrebbe non scalare è un database SQL. Un numero maggiore di istanze dell'applicazione comporterà un numero maggiore di connessioni al database, il che potrebbe causare un errore a cascata impedendo l'avvio del database.
Un modo per risolvere il problema è il seguente:
- Esegui il deployment di una nuova versione predefinita che non si connette al database.
- Arresta la versione predefinita precedente.
- Esegui il deployment di una nuova versione non predefinita che si connette al database.
- Esegui lentamente la migrazione del traffico alla nuova versione.
Una potenziale misura preventiva è progettare l'applicazione in modo da eliminare le richieste alla dipendenza utilizzando il limite di velocità adattivo.
Errore del livello di memorizzazione nella cache
Un buon modo per velocizzare le richieste è utilizzare più livelli di memorizzazione nella cache:
- Memorizzazione in una cache perimetrale
- Memcache
- Memoria all'interno dell'istanza
Un aumento improvviso della latenza potrebbe essere causato da un errore in uno di questi livelli di memorizzazione nella cache. Ad esempio, uno svuotamento della memcache può portare a un numero maggiore di richieste di Cloud Datastore più lento.