Como as instâncias são gerenciadas

As instâncias são a base do App Engine e incluem todos os recursos necessários para hospedar o aplicativo com êxito. Isso inclui o ambiente de execução da linguagem, as APIs do App Engine e o código e a memória do aplicativo. Cada instância inclui uma camada de segurança para garantir que elas não afetem umas às outras de maneira inadvertida.

Instâncias são as unidades computacionais que o App Engine usa para realizar o escalonamento automático do aplicativo. Em qualquer momento, o aplicativo pode estar em execução em uma ou várias instâncias, com solicitações espalhadas por todas elas.

Introdução às instâncias

As instâncias são residentes ou dinâmicas. Uma instância dinâmica é iniciada e desligada de maneira automática com base nas necessidades atuais. Uma instância residente é executada o tempo todo, o que pode melhorar o desempenho do aplicativo. Tanto as instâncias dinâmicas quanto as residentes instanciam o código incluído em uma versão de serviço do App Engine.

Se você usar o escalonamento manual para um aplicativo, ele será executado em instâncias residentes. Se você usar o escalonamento básico ou automático, o aplicativo será executado em instâncias dinâmicas.

A configuração do app inclui a especificação do escalonamento dos serviços dele, inclusive:

  • o número inicial de instâncias para um serviço;
  • como novas instâncias são criadas ou paradas em resposta ao tráfego;
  • a cota de tempo em que uma instância tem permissão para processar uma solicitação.

O tipo de escalonamento atribuído a um serviço determina se as instâncias são residentes ou dinâmicas:

  • Os serviços de escalonamento automático usam instâncias dinâmicas.
  • Os serviços de escalonamento manual usam instâncias residentes.
  • Os serviços de escalonamento básico usam instâncias dinâmicas.

O App Engine cobra pelo uso da instância por hora. Acompanhe o uso da instância na página Instâncias do Console do Google Cloud Platform. Caso queira especificar um limite de custos das instâncias, defina um limite de gastos. Cada serviço implantado no App Engine se comporta como um microsserviço que tem dimensionamento independente com base na configuração.

Como escalonar instâncias dinâmicas

Os aplicativos do App Engine são alimentados por um número qualquer de instâncias dinâmicas em um determinado momento, dependendo do volume das solicitações de entrada. As solicitações para o aplicativo aumentam na mesma medida que o número de instâncias dinâmicas.

O programador do App Engine decide se exibirá uma instância atual (inativa ou que aceite solicitações simultâneas) para cada nova solicitação, se colocará a solicitação em uma fila de solicitações pendentes ou se iniciará uma nova instância para essa solicitação. Essa decisão leva em conta o número de instâncias disponíveis, a rapidez com que o aplicativo exibe solicitações (latência) e quanto tempo leva para iniciar uma nova instância.

Se você usar o escalonamento automático, será possível otimizar o comportamento do programador para alcançar o equilíbrio esperado entre desempenho e custo ao definir os valores de target_cpu_utilization, target_throughput_utilization e max_concurrent_requests. (links em inglês)

Parâmetro de escalonamento automático Descrição
Meta de uso da CPU Define o limite da taxa de utilização da CPU para especificar o ponto de uso de CPU em que mais instâncias serão iniciadas para processar o tráfego.
Meta de uso da capacidade Define o ponto de capacidade para o número de solicitações simultâneas a partir do qual mais instâncias serão iniciadas para processar o tráfego.
Máximo de solicitações simultâneas Define o máximo de solicitações simultâneas que uma instância pode aceitar antes que o programador gere uma nova instância.

Assista ao vídeo Novas configurações do programador (em inglês) sobre o App Engine para ver os efeitos dessas configurações.

Cada instância tem a própria fila para solicitações de entrada. O App Engine monitora o número de solicitações que aguardam na fila de cada instância. Se ele detectar que as filas de um aplicativo estão ficando muito longas por causa de um aumento na carga, o App Engine criará automaticamente uma nova instância do aplicativo para processar essa carga.

O App Engine realiza o escalonamento vertical muito rapidamente. Portanto, se você estiver enviando lotes de solicitações aos seus serviços (por exemplo, a uma fila de tarefas para processamento), um grande número de instâncias serão criadas rapidamente. Recomendamos controlar isso por meio da limitação de taxa do número de solicitações enviadas por segundo, se possível. Por exemplo, em uma fila de tarefas do App Engine, é possível controlar a taxa de envio das tarefas.

O App Engine também escalona instâncias de maneira inversa quando os volumes de solicitações diminuem. Esse escalonamento ajuda a garantir que todas as instâncias atuais do aplicativo estejam sendo usadas com eficiência e custo-benefício ideais.

Quando um aplicativo não está sendo usado, o App Engine desativa as instâncias dinâmicas associadas dele, mas as recarregará prontamente assim que elas forem necessárias. O recarregamento das instâncias pode resultar no carregamento de solicitações e na latência adicional para usuários.

É possível especificar um número mínimo de instâncias ociosas. A definição de um número apropriado de instâncias ociosas para o aplicativo com base no volume de solicitações permite que o aplicativo atenda a todas as solicitações com pouca latência, a menos que você esteja enfrentando um volume de solicitações anormalmente alto.

Escalonar instâncias

Ao fazer o upload da versão de um serviço, o app.yaml especifica um tipo de dimensionamento e uma classe de instância que são aplicados a todas as instâncias dessa versão. O tipo de escalonamento controla como as instâncias são criadas. A classe de instância determina recursos de computação, como tamanho da memória e velocidade da CPU, e preços. Há três tipos de escalonamento: manual, básico e automático. As classes de instâncias disponíveis dependem do tipo de escalonamento.

Escalonamento manual
Um serviço com escalonamento manual usa instâncias residentes que executam continuamente o número especificado de instâncias, qualquer que seja o nível de carga. Isso permite a realização de tarefas como inicializações complexas e a execução de aplicativos que dependem do estado da memória ao longo do tempo.
Escalonamento automático
Os serviços de escalonamento automático usam instâncias dinâmicas criadas com base na taxa de solicitações, nas latências de resposta e em outras métricas do aplicativo. No entanto, se você especificar um número mínimo de instâncias ociosas, esse número será executado como instâncias residentes e todas as outras instâncias serão dinâmicas.
Escalonamento básico
Um serviço com escalonamento básico usa instâncias dinâmicas. Cada instância é criada quando o aplicativo recebe uma solicitação. A instância será desativada se o aplicativo ficar ocioso. O escalonamento básico é ideal para trabalhos intermitentes ou determinados pela atividade dos usuários.

Esta tabela compara os recursos de desempenho dos três tipos de escalonamento:

Recurso Escalonamento automático Escalonamento manual Escalonamento básico
Prazos Prazo de 60 segundos para solicitações HTTP, prazo de 10 minutos para tarefas de filas de tarefas. As solicitações podem ser executadas por até 24 horas. Uma instância com escalonamento manual pode escolher processar /_ah/start e executar um programa ou script por muitas horas sem retornar um código de resposta HTTP. As tarefas de fila de tarefas podem durar até 24 horas. Igual ao escalonamento manual.
Threads em segundo plano Não permitido Permitido Permitido
Residência As instâncias são removidas da memória com base em padrões de uso. As instâncias permanecem na memória e o estado é preservado em todas as solicitações. Quando as instâncias são reiniciadas, um /_ah/stop aparece nos registros. Se houver um gancho de encerramento registrado, ele terá 30 segundos para ser concluído antes que o encerramento ocorra. As instâncias são removidas com base no parâmetro idle_timeout. Se uma instância estiver ociosa, talvez por não ter recebido nenhuma solicitação, por mais do que o idle_timeout, ela será removida.
Inicialização e encerramento As instâncias são criadas sob demanda para manipular solicitações e são desativadas automaticamente quando ficam ociosas. As instâncias recebem uma solicitação de início automaticamente pelo App Engine sob a forma de uma solicitação GET vazia para /_ah/start. Uma instância que é parada manualmente tem 30 segundos para terminar de processar as solicitações antes de ser encerrada à força. As instâncias são criadas sob demanda para processar solicitações e são desativadas automaticamente quando ficam ociosas com base no parâmetro de configuração idle_timeout. Assim como acontece com o escalonamento manual, uma instância que é parada manualmente tem 30 segundos para terminar de processar as solicitações antes de ser encerrada à força.
Endereçabilidade de instâncias As instâncias são anônimas. A instância "i" da versão "v" do serviço "s" pode ser acessada no URL: http://i.v.s.app_id.appspot.com. Se um mapeamento de subdomínio com caracteres curinga de um domínio personalizado for configurado, também será possível acessar um serviço ou qualquer instância dele por meio de um URL no formato http://s.domain.com ou http://i.s.domain.com. É possível armazenar em cache o estado de maneira confiável em cada instância e recuperá-lo nas solicitações seguintes . Igual ao escalonamento manual.
Escalonamento O App Engine escalona o número de instâncias automaticamente em resposta ao volume de processamento. Esse escalonamento é fatorado nas configurações de automatic_scaling fornecidas por versão no arquivo de configuração. Você configura o número de instâncias de cada versão no arquivo de configuração desse serviço. O número de instâncias geralmente corresponde ao tamanho de um conjunto de dados mantido na memória ou à taxa de transferência desejada para trabalho off-line. É possível ajustar o número de instâncias de uma versão escalada manualmente com muita rapidez, sem interromper instâncias atualmente em execução, usando a função set_num_instances da API de módulos. Um serviço com escalonamento básico é configurado com a definição do número máximo de instâncias no parâmetro max_instances da configuração basic_scaling. O número de instâncias ativas é escalonado com o volume de processamento.
Cota de uso diária gratuita 28 instância/horas 8 instância/horas 8 instância/horas

Ciclo de vida da instância

Estados de instância

Uma instância de um serviço com escalonamento automático está sempre em execução. No entanto, uma instância de um serviço com escalonamento manual ou básico pode estar em execução ou parada. Todas as instâncias do mesmo serviço e versão têm estados iguais. Você altera o estado das instâncias gerenciando as versões. É possível:

Inicialização

Cada instância de serviço é criada em resposta a uma solicitação de inicialização, que é uma solicitação HTTP GET vazia para /_ah/start. O App Engine envia essa solicitação para criar a instância. Os usuários não podem enviar uma solicitação para /_ah/start. As instâncias de escalonamento manual e básico precisam responder à solicitação de inicialização antes de processar outra. Essa solicitação pode ser usada para duas finalidades:

  • Iniciar um programa executado indefinidamente, sem aceitar outras solicitações.
  • Inicializar uma instância antes que ela receba mais tráfego.

As instâncias de escalonamento automático, manual e básico são inicializadas de maneira diferente. Quando você inicia uma instância de escalonamento manual, o App Engine envia imediatamente uma solicitação /_ah/start para cada instância. Quando você inicia uma instância de um serviço de escalonamento básico, o App Engine permite que ela aceite tráfego, mas a solicitação /_ah/start não é enviada para uma instância até receber a primeira solicitação do usuário. Várias instâncias de escalonamento básico só são iniciadas conforme necessário, para processar o tráfego aumentado. As instâncias de escalonamento automático não recebem solicitações /_ah/start.

Quando uma instância responde à solicitação /_ah/start com um código de status HTTP de 200–299 ou 404, ela é considerada bem-sucedida na inicialização e pode processar solicitações adicionais. Do contrário, o App Engine encerra a instância. As instâncias de escalonamento manual são reiniciadas imediatamente, e as de escalonamento básico só são reiniciadas quando necessário para veicular o tráfego.

Encerramento

O processo de encerramento pode ser acionado por uma variedade de eventos planejados e não planejados, como estes:

  • Você para manualmente uma instância.
  • Você implanta uma versão atualizada no serviço.
  • A instância excede a memória máxima do instance_class configurado.
  • O aplicativo esgotou a cota de instância/horas.
  • A instância é transferida para uma máquina diferente porque a máquina em que ela está sendo executada foi reiniciada ou porque o App Engine moveu a instância para melhorar a distribuição de carga.
Há duas maneiras de um app determinar se uma instância de escalonamento manual está prestes a ser desligada. Primeiro, o método is_shutting_down() de google.appengine.api.runtime começa a retornar true. Segundo (e preferencial), registre um gancho de desligamento, conforme descrito abaixo.

Quando o App Engine começa a desligar uma instância, as solicitações existentes têm 30 segundos para serem concluídas, e as novas retornam 404 imediatamente. Se uma instância está processando uma solicitação, o App Engine pausa a solicitação e executa o gancho de desligamento. Caso não haja uma solicitação ativa, o App Engine enviará uma /_ah/stop, que executa o gancho de desligamento. A solicitação /_ah/stop ignora a lógica de processamento normal e não pode ser processada pelo código do usuário. O único objetivo dela é invocar o gancho de desligamento. Se você gera uma exceção em seu gancho de desligamento durante o processamento de outra solicitação, ela aparece em um balão na solicitação, em que você pode capturá-la.

Caso você tenha ativado solicitações simultâneas especificando threadsafe: true em app.yaml (o padrão), gerar uma exceção de um gancho de desligamento copiará essa exceção para todos os threads. A seguinte amostra de código representa um gancho de desligamento básico:

from google.appengine.api import apiproxy_stub_map
from google.appengine.api import runtime

def my_shutdown_hook():
  apiproxy_stub_map.apiproxy.CancelApiCalls()
  save_state()
  # May want to raise an exception

runtime.set_shutdown_hook(my_shutdown_hook)

Como alternativa, a seguinte amostra determina como usar o método is_shutting_down():

while more_work_to_do and not runtime.is_shutting_down():
  do_some_work()
  save_state()

Como carregar solicitações

Quando o App Engine cria uma nova instância para o aplicativo, ela precisa primeiro carregar todas as bibliotecas e os recursos necessários para processar a solicitação. Isso acontece durante a primeira solicitação para a instância, chamada de solicitação de carregamento. Durante esse processo, o aplicativo passa pela inicialização, o que faz a solicitação demorar mais.

As práticas recomendadas a seguir permitem reduzir a duração das solicitações de carregamento:

  • Carregue apenas o código necessário para a inicialização.
  • Acesse o disco o mínimo possível.
  • Em alguns casos, o carregamento do código a partir de um arquivo zip ou jar é mais rápido do que o carregamento de muitos arquivos separados.

Solicitações de aquecimento

Solicitações de aquecimento são um tipo específico de solicitação que carrega o código do aplicativo em uma instância com antecedência, antes que solicitações ativas sejam realizadas. As instâncias de escalonamento manual ou básico não recebem uma solicitação /_ah/warmup.

Consulte Como configurar solicitações de aquecimento para saber mais sobre como usá-las.

Tempo de atividade da instância

O App Engine tenta manter as instâncias de escalonamento manual e básico em execução indefinidamente. No entanto, neste momento, não há tempo de atividade garantido para instâncias de escalonamento manual e básico. As falhas de hardware e software que causam o encerramento prematuro ou reinicializações frequentes podem ocorrer sem aviso prévio e levar um tempo considerável para serem resolvidas. Assim, você precisa criar seu aplicativo de um modo que tolere essas falhas.

Veja a seguir algumas boas estratégias para evitar a inatividade devido a reinícios da instância:

  • Reduza o tempo necessário para a reinicialização das instâncias ou para que novas instâncias sejam inicializadas.
  • Para cálculos de longa duração, crie checkpoints periodicamente para que seja possível retomar a partir desse estado.
  • O aplicativo precisa ser "sem estado" para que nada seja armazenado na instância.
  • Use filas para executar tarefas assíncronas.
  • Se você configurar as instâncias para escalonamento manual:
    • Use o balanceamento de carga em várias instâncias;
    • Configure mais instâncias do que o necessário para processar o tráfego normal;
    • escreva a lógica de fallback que usa resultados em cache quando uma instância de escalonamento manual não está disponível.

Faturamento da instância

Em geral, as instâncias são cobradas por minuto pelo tempo de atividade delas, além de terem uma taxa de inicialização de 15 minutos. Consulte a página de preços para ver detalhes. Você só será cobrado até o número máximo de instâncias ociosas definido para cada serviço. A sobrecarga de ambiente de execução é contada em relação à memória da instância. Ela será maior para aplicativos Java do que Python.

O faturamento é um pouco diferente em instâncias residentes e dinâmicas:

  • Para instâncias residentes, o faturamento termina 15 minutos após o encerramento da instância.
  • Para instâncias dinâmicas, o faturamento termina 15 minutos após a conclusão do processamento da última solicitação.
Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Ambiente padrão do App Engine para Python 2