Em muitos casos, a latência elevada na sua aplicação acaba por resultar em erros do servidor 5xx. Uma vez que a causa principal do erro e dos picos de latência pode ser a mesma, aplique as seguintes estratégias para resolver problemas de latência:
Defina o âmbito do problema de latência
Defina o âmbito do problema fazendo as seguintes perguntas:
- Que aplicações, serviços e versões são afetados por este problema?
- Que pontos finais específicos no serviço são afetados por este problema?
- Isto afeta todos os clientes a nível global ou um subconjunto específico de clientes?
- Qual é a hora de início e de fim do incidente? Considere especificar o fuso horário.
- Quais são os erros específicos?
- Qual é o delta de latência observado, que é normalmente especificado como um aumento num percentil específico? Por exemplo, a latência aumentou 2 segundos no 90.º percentil.
- Como mediu a latência? Em particular, mediu-a no cliente ou está visível no Cloud Logging ou nos dados de latência do Cloud Monitoring que a infraestrutura de publicação do App Engine fornece?
- Quais são as dependências do seu serviço e alguma delas tem incidentes?
- Fez alguma alteração recente ao código, à configuração ou à carga de trabalho que tenha acionado este problema?
Um serviço pode ter a sua própria monitorização e registo personalizados que pode usar para restringir ainda mais o âmbito do problema. Definir o âmbito do problema vai ajudar a identificar a causa principal provável e determinar os passos seguintes de resolução de problemas.
Identifique a causa
Determine que componente no caminho do pedido tem maior probabilidade de estar a causar a latência ou os erros. Os principais componentes no caminho do pedido são os seguintes:
Cliente --> Internet --> Front-end da Google (GFE) --> Infraestrutura de publicação do App Engine --> Instância do serviço
Se as informações anteriores não indicarem a origem da falha, aplique as seguintes estratégias enquanto revê o estado e o desempenho da instância do serviço:
Monitorize os registos de pedidos do App Engine. Se vir erros de código de estado HTTP ou latência elevada nesses registos, o problema reside provavelmente na instância que executa o seu serviço.
Se o número de instâncias de serviço não tiver sido dimensionado para corresponder aos níveis de tráfego, as suas instâncias podem estar sobrecarregadas, o que resulta em erros e latência elevados.
Se vir erros ou latência elevados no Cloud Monitoring, o problema pode estar a montante do equilibrador de carga, que regista as métricas do App Engine. Na maioria dos casos, isto aponta para um problema nas instâncias do serviço.
Se vir uma latência elevada ou erros nas métricas de monitorização, mas não nos registos de pedidos, isso indica uma falha no equilíbrio de carga ou uma falha grave da instância que está a impedir o encaminhamento de pedidos pelo equilibrador de carga. Para distinguir entre estes casos, consulte os registos de pedidos antes do início do incidente. Se os registos de pedidos mostrarem um aumento da latência antes da falha, as instâncias da aplicação estavam a começar a falhar antes de o equilibrador de carga parar de encaminhar pedidos para as mesmas.
Resolver problemas
Esta secção descreve as estratégias de resolução de problemas de questões de latência elevada dos seguintes componentes no caminho do pedido:
- Internet
- Google Front End (GFE)
- Infraestrutura de publicação do App Engine
- Instância da aplicação
- Relações de dependência da aplicação
Internet
A sua aplicação pode ter problemas de latência devido a uma conetividade fraca ou a uma largura de banda inferior.
Conetividade à Internet fraca
Para determinar se o problema é uma conetividade à Internet fraca, execute o seguinte comando no cliente:
$ curl -s -o /dev/null -w '%{time_connect}\n' <hostname>
O valor de time_connect
representa a latência da ligação do cliente ao Google Front End mais próximo.
Para ligações lentas, resolva problemas adicionais através do comando traceroute
para determinar que salto na rede causa o atraso.
Executar testes a partir de clientes em diferentes localizações geográficas. O App Engine encaminha automaticamente os pedidos para o centro de dados da Google mais próximo, que varia com base na localização do cliente.
Largura de banda baixa
A aplicação pode estar a responder rapidamente. No entanto, os gargalos da rede atrasam o envio de pacotes pela infraestrutura de publicação do App Engine, o que torna as respostas mais lentas.
Google Front End (GFE)
A sua aplicação pode ter problemas de latência devido ao encaminhamento incorreto, a pedidos paralelos enviados a partir de clientes HTTP/2 ou à terminação de ligações SSL.
Mapeie um IP de cliente para uma região geográfica
A Google resolve o nome do anfitrião da aplicação App Engine para o GFE mais próximo do cliente, com base no endereço IP do cliente que usa na pesquisa de DNS. Se o resolvedor de DNS do cliente não estiver a usar o protocolo EDNS0, a Google pode não encaminhar os pedidos do cliente para o GFE mais próximo.
Bloqueio de cabeça de fila HTTP/2
Os clientes HTTP/2 que enviam vários pedidos em paralelo podem observar uma latência elevada devido ao bloqueio de cabeça de fila no GFE. Para resolver este problema, os clientes têm de usar o protocolo QUIC.
Terminação SSL para domínios personalizados
O GFE pode terminar a ligação SSL. Se estiver a usar um domínio personalizado em vez de um domínio, a terminação SSL requer um salto adicional.appspot.com
Isto pode adicionar latência para aplicações em execução em algumas regiões. Para mais informações, consulte o artigo Mapear domínios personalizados.
Infraestrutura de publicação do App Engine
Pode observar uma latência elevada na sua aplicação devido a incidentes ao nível do serviço ou ao dimensionamento automático.
Incidentes ao nível do serviço
A Google publica detalhes de um incidente grave ao nível do serviço no painel de controlo Estado do serviço. No entanto, a Google implementa as atualizações gradualmente, pelo que é improvável que um incidente ao nível do serviço afete todas as suas instâncias de uma só vez.
Escala automática
A latência elevada ou os erros podem resultar dos seguintes cenários de dimensionamento automático:
Aumentar o tráfego demasiado rapidamente: o ajuste automático do App Engine pode não ajustar as suas instâncias tão rapidamente quanto o aumento do tráfego, o que leva a uma sobrecarga temporária. Normalmente, a sobrecarga ocorre quando o tráfego é gerado por um programa de computador em vez de utilizadores finais. Para resolver este problema, limite o sistema que gera o tráfego.
Picos no tráfego: os picos no tráfego podem causar uma latência elevada nos casos em que um serviço com escalamento automático precisa de ser aumentado mais rapidamente do que o possível, sem afetar a latência. Normalmente, o tráfego de utilizadores finais não provoca picos de tráfego frequentes. Se vir picos de tráfego, deve investigar a causa. Se um sistema de processamento em lote estiver a ser executado em intervalos, pode suavizar o tráfego ou usar definições de escalabilidade diferentes.
Definições do escalador automático: o escalador automático pode ser configurado com base nas características de escalamento do seu serviço. Os parâmetros de escalabilidade podem tornar-se não ideais nos seguintes cenários:
As definições de escalabilidade do ambiente padrão do App Engine podem causar latência se forem definidas de forma demasiado agressiva. Se vir respostas do servidor com o código de estado
500
e a mensagem "Request was aborted after waiting too long to attempt to service your request" (O pedido foi anulado após esperar demasiado tempo para tentar processar o seu pedido) nos registos, significa que o pedido excedeu o tempo limite na fila pendente enquanto esperava por uma instância inativa.Pode ver um aumento do tempo pendente com o dimensionamento manual, mesmo quando provisionou instâncias suficientes. Recomendamos que não use o dimensionamento manual se a sua aplicação publicar tráfego de utilizadores finais. O escalamento manual é melhor para cargas de trabalho, como filas de tarefas.
O dimensionamento básico minimiza os custos à custa da latência. Recomendamos que não use a escalabilidade básica para serviços sensíveis à latência.
A predefinição de escalabilidade do App Engine oferece uma latência ideal para a maioria dos serviços. Se continuar a ver pedidos com um tempo de pendência elevado, especifique um número mínimo de instâncias. Se ajustar as definições de escalabilidade para reduzir os custos minimizando as instâncias inativas, corre o risco de picos de latência se a carga aumentar subitamente.
Recomendamos que compare o desempenho com as predefinições de ajuste de escala e, em seguida, execute uma nova comparação após cada alteração a estas definições.
Implementações
A latência elevada pouco depois de uma implementação indica que não aumentou a escala suficientemente antes de migrar o tráfego. As instâncias mais recentes podem não ter aquecido as caches locais e são publicadas mais lentamente do que as instâncias mais antigas.
Para evitar picos de latência, não implemente um serviço do App Engine com o mesmo nome da versão que uma versão existente do serviço. Se reutilizar um nome de versão existente, não pode migrar lentamente o tráfego para a nova versão. Os pedidos podem ser mais lentos porque o App Engine reinicia todas as instâncias num curto período de tempo. Também tem de voltar a implementar se quiser reverter para a versão anterior.
Instância da aplicação
Esta secção descreve as estratégias comuns que pode aplicar às instâncias da aplicação e ao código-fonte para otimizar o desempenho e reduzir a latência.
Código da aplicação
Os problemas no código da aplicação podem ser difíceis de depurar, especialmente se forem intermitentes ou não reproduzíveis.
Para resolver problemas, faça o seguinte:
Para diagnosticar os seus problemas, recomendamos que instrumente a sua aplicação usando registos, monitorização e rastreio. Também pode usar o Cloud Profiler.
Tente reproduzir o problema num ambiente de desenvolvimento local que lhe permita executar ferramentas de depuração específicas do idioma que podem não ser possíveis de executar no App Engine.
Para compreender melhor como a sua aplicação falha e que gargalos ocorrem, teste o carregamento da aplicação até à falha. Defina uma contagem máxima de instâncias e, em seguida, aumente gradualmente a carga até a aplicação falhar.
Se o problema de latência estiver correlacionado com a implementação de uma nova versão do código da aplicação, reverta para determinar se a nova versão causou o incidente. No entanto, se fizer implementações contínuas, as implementações frequentes dificultam a determinação de se a implementação causou o incidente com base na hora de início.
A sua aplicação pode armazenar definições de configuração no Datastore ou noutro local. Crie uma cronologia das alterações de configuração para determinar se alguma delas coincide com o início da latência elevada.
Alteração da carga de trabalho
Uma alteração da carga de trabalho pode causar uma latência elevada. Algumas métricas de monitorização que indicam alterações na carga de trabalho incluem qps
, a utilização da API e a latência. Verifique também se existem alterações nos tamanhos dos pedidos e das respostas.
Pressão da memória
Se a monitorização mostrar um padrão de dentes de serra na utilização de memória ou uma diminuição na utilização de memória que se correlaciona com as implementações, uma fuga de memória pode ser a causa dos problemas de desempenho. Uma fuga de memória também pode causar uma recolha de lixo frequente que leva a uma latência mais elevada. Se não conseguir detetar este problema no código, experimente aprovisionar instâncias maiores com mais memória.
Fuga de recursos
Se uma instância da sua aplicação mostrar uma latência crescente que se correlaciona com a idade da instância, pode ter uma fuga de recursos que cause problemas de desempenho. A latência diminui após a conclusão de uma implementação. Por exemplo, uma estrutura de dados que fica mais lenta ao longo do tempo devido a uma maior utilização da CPU pode fazer com que qualquer carga de trabalho limitada pela CPU fique mais lenta.
Otimização de código
Para reduzir a latência no App Engine, otimize o código através dos seguintes métodos:
Trabalho offline: use o Cloud Tasks para impedir que os pedidos dos utilizadores bloqueiem a aplicação à espera da conclusão do trabalho, como o envio de emails.
Chamadas de API assíncronas: certifique-se de que o seu código não está bloqueado à espera que uma chamada de API seja concluída.
Chamadas API em lote: a versão em lote das chamadas API é normalmente mais rápida do que o envio de chamadas individuais.
Desnormalizar modelos de dados: reduza a latência das chamadas feitas à camada de persistência de dados desnormalizando os seus modelos de dados.
Dependências de aplicações
Monitorize as dependências da sua aplicação para detetar se os picos de latência estão correlacionados com uma falha de dependência.
Uma alteração da carga de trabalho e um aumento no tráfego podem fazer com que a latência de uma dependência aumente.
Dependência sem redimensionamento
Se a dependência da sua aplicação não for dimensionada à medida que o número de instâncias do App Engine aumenta, a dependência pode ficar sobrecarregada quando o tráfego aumenta. Um exemplo de uma dependência que pode não ser escalável é uma base de dados SQL. Um número mais elevado de instâncias da aplicação leva a um número mais elevado de ligações à base de dados, o que pode causar uma falha em cascata ao impedir o arranque da base de dados. Para resolver este problema, faça o seguinte:
- Implemente uma nova versão predefinida que não se ligue à base de dados.
- Desative a versão predefinida anterior.
- Implemente uma nova versão não predefinida que se ligue à base de dados.
- Migre lentamente o tráfego para a nova versão.
Como medida preventiva, crie a sua aplicação para rejeitar pedidos à dependência através da limitação adaptável.
Falha na camada de colocação em cache
Para acelerar os pedidos, use várias camadas de colocação em cache, como a colocação em cache de limite, Memcache e memória na instância. Uma falha numa destas camadas de colocação em cache pode causar um aumento súbito da latência. Por exemplo, uma limpeza do Memcache pode fazer com que mais pedidos sejam enviados para um Datastore mais lento.