ID da região
O REGION_ID
é um código abreviado que a Google atribui com base na região que seleciona quando cria a sua app. O código não corresponde a um país ou uma província, embora alguns IDs de regiões possam parecer semelhantes aos códigos de países e províncias usados frequentemente. Para apps criadas após
fevereiro de 2020, REGION_ID.r
está incluído nos
URLs do App Engine. Para apps existentes criadas antes desta data, o
ID da região é opcional no URL.
Saiba mais acerca dos IDs de regiões.
Este documento descreve como a sua aplicação do App Engine recebe pedidos e envia respostas.
Para mais detalhes, consulte a referência de cabeçalhos e respostas de pedidos.
Se a sua aplicação usar serviços, pode enviar pedidos para um serviço específico ou uma versão específica desse serviço. Para mais informações sobre a capacidade de resposta do serviço, consulte o artigo Como os pedidos são encaminhados.
Processar pedidos
A sua aplicação é responsável por iniciar um servidor Web e processar pedidos. Pode usar qualquer framework Web disponível para a sua linguagem de desenvolvimento.
O App Engine executa várias instâncias da sua aplicação e cada instância tem o seu próprio servidor Web para processar pedidos. Qualquer pedido pode ser encaminhado para qualquer instância, pelo que os pedidos consecutivos do mesmo utilizador não são necessariamente enviados para a mesma instância. Uma instância pode processar vários pedidos em simultâneo. O número de instâncias pode ser ajustado automaticamente à medida que o tráfego muda.
Também pode alterar o número de pedidos simultâneos que uma instância pode processar
definindo o elemento max_concurrent_requests
no ficheiro app.yaml.
app.yaml
da aplicação. O tempo de execução do Python 2.7 suporta a norma WSGI e a norma CGI para
compatibilidade com versões anteriores. O WSGI é preferível e algumas funcionalidades do Python 2.7 não funcionam sem ele. A configuração dos controladores de scripts da sua aplicação determina se um pedido é processado através de WSGI ou CGI.
O seguinte script Python responde a um pedido com um cabeçalho HTTP e a mensagem Hello, World!
.
Para enviar vários pedidos a cada servidor Web em paralelo, marque a sua aplicação como segura para threads adicionando um threadsafe: true
ao seu ficheiro app.yaml
. Os pedidos simultâneos não estão disponíveis se algum controlador de scripts usar CGI.
Quotas e limites
O App Engine atribui automaticamente recursos à sua aplicação à medida que o tráfego aumenta. No entanto, isto está sujeito às seguintes restrições:
O App Engine reserva capacidade de escalabilidade automática para aplicações com baixa latência, em que a aplicação responde a pedidos em menos de um segundo.
As aplicações que estão fortemente limitadas pela CPU também podem incorrer em alguma latência adicional para partilhar recursos de forma eficiente com outras aplicações nos mesmos servidores. Os pedidos de ficheiros estáticos estão isentos destes limites de latência.
Cada pedido recebido para a aplicação conta para o limite de pedidos. Os dados enviados em resposta a um pedido contam para o limite de largura de banda de saída (faturável).
Os pedidos HTTP e HTTPS (seguros) são contabilizados para os limites de pedidos, largura de banda de entrada (faturável) e largura de banda de saída (faturável). A Google Cloud página de detalhes da quota da consola também comunica pedidos seguros, largura de banda de entrada segura e largura de banda de saída segura como valores separados para fins informativos. Apenas os pedidos HTTPS contam para estes valores. Para mais informações, consulte a página Quotas.
Os seguintes limites aplicam-se especificamente à utilização de controladores de pedidos:
Limite | Montante |
---|---|
Tamanho do pedido | 32 megabytes |
Tamanho da resposta | 32 megabytes |
Tempo limite de pedido | Depende do tipo de dimensionamento que a sua app usa |
Número total máximo de ficheiros (ficheiros de apps e ficheiros estáticos) | 10 000 no total 1000 por diretório |
Tamanho máximo de um ficheiro de aplicação | 32 megabytes |
Tamanho máximo de um ficheiro estático | 32 megabytes |
Tamanho total máximo de todos os ficheiros estáticos e de aplicações | O primeiro gigabyte é gratuito 0,026$ por gigabyte por mês após o primeiro gigabyte |
Tempo limite de pedido pendente | 10 segundos |
Tamanho máximo de um único campo de cabeçalho de pedido | 8 kilobytes para tempos de execução de segunda geração no ambiente padrão. Os pedidos a estes tempos de execução com campos de cabeçalho que excedam 8 kilobytes devolvem erros HTTP 400. |
Limites aos pedidos
Todos os pedidos HTTP/2 são traduzidos em pedidos HTTP/1.1 quando são encaminhados para o servidor de aplicações.
Limites de respostas
As respostas dinâmicas estão limitadas a 32 MB. Se um controlador de scripts gerar uma resposta superior a este limite, o servidor envia uma resposta vazia com um código de estado 500 Internal Server Error. Esta limitação não se aplica a respostas que fornecem dados do Blobstore antigo ou do Cloud Storage.
O limite do cabeçalho de resposta é de 8 KB para os tempos de execução de segunda geração. Os cabeçalhos de resposta que excedam este limite devolvem erros HTTP 502, com registos a apresentar
upstream sent too big header while reading response header from upstream
.
Cabeçalhos do pedido
Um pedido HTTP de entrada inclui os cabeçalhos HTTP enviados pelo cliente. Por motivos de segurança, alguns cabeçalhos são limpos ou alterados por proxies intermédios antes de chegarem à aplicação.
Para mais informações, consulte a referência de cabeçalhos de pedidos.
Processar limites de tempo de pedidos
O App Engine está otimizado para aplicações com pedidos de curta duração, normalmente, aqueles que demoram algumas centenas de milissegundos. Uma app eficiente responde rapidamente à maioria dos pedidos. Uma app que não o faça não é bem dimensionada com a infraestrutura do App Engine. Para garantir este nível de desempenho, existe um limite de tempo de pedido imposto pelo sistema ao qual todas as apps têm de responder.
Se a sua app exceder este prazo, o App Engine interrompe o controlador de pedidos. O ambiente de tempo de execução do Python consegue isto ao gerar uma exceçãoDeadlineExceededError
de google.appengine.runtime
. Se o controlador de pedidos não detetar esta exceção, tal como acontece com todas as exceções não detetadas, o ambiente de tempo de execução devolve um erro de servidor HTTP 500 ao cliente.
O controlador de pedidos pode captar este erro para personalizar a resposta. O ambiente de tempo de execução dá ao controlador de pedidos um pouco mais de tempo (menos de um segundo) após gerar a exceção para preparar uma resposta personalizada.
Se o controlador não tiver devolvido uma resposta ou gerado uma exceção até ao prazo de 2 segundos, o controlador é parado e é devolvida uma resposta de erro predefinida.
Responses
O App Engine chama o script do controlador com umRequest
e aguarda que o script seja devolvido. Todos os dados escritos no fluxo de saída padrão são enviados como a resposta HTTP.
Existem limites de tamanho que se aplicam à resposta que gera, e a resposta pode ser modificada antes de ser devolvida ao cliente.
Para mais informações, consulte a referência de respostas de pedidos.Respostas graduais
O App Engine não suporta respostas de streaming em que os dados são enviados em blocos incrementais para o cliente enquanto um pedido está a ser processado. Todos os dados do seu código são recolhidos conforme descrito acima e enviados como uma única resposta HTTP.
Compressão de respostas
O App Engine faz o seu melhor para fornecer conteúdo comprimido (com gzip) a clientes que o suportam. Para determinar se o conteúdo deve ser comprimido, o App Engine faz o seguinte quando recebe um pedido:Confirma se o cliente pode receber respostas comprimidas de forma fiável através da visualização dos cabeçalhos
Accept-Encoding
eUser-Agent
no pedido. Esta abordagem evita alguns erros conhecidos com conteúdo comprimido com gzip em navegadores populares.Confirma se a compressão do conteúdo é adequada através da visualização do cabeçalho
Content-Type
que configurou para o processador de respostas. Em geral, a compressão é adequada para tipos de conteúdo baseados em texto e não para tipos de conteúdo binários.
Tenha em conta o seguinte:
Um cliente pode forçar a compressão de tipos de conteúdo baseados em texto definindo os cabeçalhos de pedido
Accept-Encoding
eUser-Agent
comogzip
.Se um pedido não especificar
gzip
no cabeçalhoAccept-Encoding
, o App Engine não comprime os dados de resposta.O front-end da Google armazena em cache as respostas dos controladores de ficheiros estáticos e de diretórios do App Engine. Consoante vários fatores, como o tipo de dados de resposta que é colocado em cache primeiro, os cabeçalhos
Vary
que especificou na resposta e os cabeçalhos incluídos no pedido, um cliente pode pedir dados comprimidos, mas receber dados não comprimidos e vice-versa. Para mais informações, consulte o artigo Colocação em cache de respostas.
Colocação em cache de respostas
O front-end da Google e, potencialmente, o navegador do utilizador e outros servidores proxy de colocação em cache intermédios, vão colocar em cache as respostas da sua app, conforme indicado nos cabeçalhos de colocação em cache padrão que especificar na resposta. Pode especificar estes cabeçalhos de resposta através da sua framework, diretamente no seu código ou através dos processadores de ficheiros estáticos e diretórios do App Engine.
No frontend da Google, a chave da cache é o URL completo do pedido.
Colocar conteúdo estático em cache
Para garantir que os clientes recebem sempre conteúdo estático atualizado assim que é publicado, recomendamos que publique conteúdo estático a partir de diretórios com controlo de versões, como css/v1/styles.css
. O front-end da Google não valida a cache (verifica se existe conteúdo atualizado) até a cache expirar. Mesmo após o
cache expirar, o cache não é atualizado até que o conteúdo no URL do pedido
seja alterado.
Os seguintes cabeçalhos de resposta que pode
definir em
app.yaml
influenciam como e quando o front-end da Google coloca conteúdo em cache:
Cache-Control
deve ser definido comopublic
para que o front-end da Google coloque em cache o conteúdo. O conteúdo também pode ser colocado em cache pelo front-end da Google, a menos que especifique uma diretivaCache-Control
private
ouno-store
. Se não definir este cabeçalho emapp.yaml
, o App Engine adiciona-o automaticamente a todas as respostas processadas por um ficheiro estático ou um controlador de diretório. Para mais informações, consulte o artigo Cabeçalhos adicionados ou substituídos.Vary
: Para permitir que a cache devolva respostas diferentes para um URL com base nos cabeçalhos enviados no pedido, defina um ou mais dos seguintes valores no cabeçalho de respostaVary
:Accept
,Accept-Encoding
,Origin
ouX-Origin
Devido ao potencial de elevada cardinalidade, os dados não são colocados em cache para outros valores de
Vary
.Por exemplo:
Especifique o seguinte cabeçalho da resposta:
Vary: Accept-Encoding
A sua app recebe um pedido que contém o cabeçalho
Accept-Encoding: gzip
. O App Engine devolve uma resposta comprimida e o Google Frontend armazena em cache a versão comprimida com gzip dos dados de resposta. Todos os pedidos subsequentes para este URL que contenham o cabeçalhoAccept-Encoding: gzip
vão receber os dados comprimidos com gzip da cache até que a cache seja invalidada (devido a alterações no conteúdo após a expiração da cache).A sua app recebe um pedido que não contém o cabeçalho
Accept-Encoding
. O App Engine devolve uma resposta não comprimida e o Google Frontend armazena em cache a versão não comprimida dos dados de resposta. Todos os pedidos subsequentes para este URL que não contenham o cabeçalhoAccept-Encoding
vão receber os dados comprimidos da cache até que a cache seja invalidada.
Se não especificar um cabeçalho de resposta
Vary
, o front-end da Google cria uma única entrada de cache para o URL e usa-a para todos os pedidos, independentemente dos cabeçalhos no pedido. Por exemplo:- Não especifica o cabeçalho da resposta
Vary: Accept-Encoding
. - Um pedido contém o cabeçalho
Accept-Encoding: gzip
e a versão comprimida com gzip dos dados de resposta é colocada em cache. - Um segundo pedido não contém o cabeçalho
Accept-Encoding: gzip
. No entanto, uma vez que a cache contém uma versão comprimida com gzip dos dados de resposta, a resposta é comprimida com gzip, mesmo que o cliente tenha pedido dados não comprimidos.
Os cabeçalhos no pedido também influenciam o armazenamento em cache:
- Se o pedido contiver um cabeçalho
Authorization
, o conteúdo não é colocado em cache pelo front-end da Google.
Expiração da cache
Por predefinição, os cabeçalhos de colocação em cache que os controladores de ficheiros estáticos e de diretórios do App Engine adicionam às respostas indicam aos clientes e aos proxies Web, como o frontend da Google, que a cache expira após 10 minutos.
Depois de um ficheiro ser transmitido com um determinado tempo de expiração, geralmente, não existe forma de o limpar das caches de proxy Web, mesmo que o utilizador limpe a sua própria cache do navegador. A nova implementação de uma nova versão da app não repõe nenhuma cache. Por conseguinte, se alguma vez planear modificar um ficheiro estático, este deve ter um prazo de validade curto (inferior a uma hora). Na maioria dos casos, o tempo de expiração predefinido de 10 minutos é adequado.
Pode alterar a expiração predefinida de todos os gestores de ficheiros e diretórios estáticos especificando o elemento default_expiration
no ficheiro app.yaml
. Para definir horas de validade específicas para controladores individuais, especifique o elemento expiration
no elemento do controlador no seu ficheiro app.yaml
.
O valor especificado no tempo dos elementos de expiração é usado para definir os cabeçalhos de resposta HTTP Cache-Control
e Expires
.
Colocação em cache de apps
O ambiente de execução do Python armazena em cache os módulos importados entre pedidos num único servidor Web, de forma semelhante ao modo como uma aplicação Python autónoma carrega um módulo apenas uma vez, mesmo que o módulo seja importado por vários ficheiros. Uma vez que os controladores WSGI são módulos, são colocados em cache entre pedidos. Os scripts de processador de CGI só são colocados em cache se fornecerem uma rotinamain()
; caso contrário, o script de processador de CGI é carregado para cada pedido.
O armazenamento em cache de apps oferece uma vantagem significativa no tempo de resposta. Recomendamos que todos os scripts de processamento de CGI usem uma rotina main(), conforme descrito abaixo.
As importações são colocadas em cache
Por questões de eficiência, o servidor Web mantém os módulos importados na memória e não os volta a carregar nem a reavaliar em pedidos subsequentes à mesma aplicação no mesmo servidor. A maioria dos módulos não inicializa dados globais nem tem outros efeitos secundários quando são importados, pelo que a colocação em cache dos mesmos não altera o comportamento da aplicação.
Se a sua aplicação importar um módulo que dependa do módulo que está a ser avaliado para cada pedido, a aplicação tem de ter em conta este comportamento de colocação em cache.
Colocação em cache de controladores CGI
Pode indicar ao App Engine para colocar em cache o próprio script do controlador CGI, além dos módulos importados. Se o script do controlador definir uma função denominada
main()
, o script e o respetivo ambiente global são colocados em cache como um módulo importado. O primeiro pedido do script num determinado servidor Web
avalia o script normalmente. Para pedidos subsequentes, o App Engine chama a função main()
no ambiente em cache.
Para colocar em cache um script de controlador, o App Engine tem de conseguir chamar main()
sem argumentos. Se o script do controlador não definir uma função main()
ou a função main()
exigir argumentos (que não têm predefinições), o App Engine carrega e avalia todo o script para cada pedido.
Manter o código Python analisado na memória poupa tempo e permite respostas mais rápidas. A colocação em cache do ambiente global também tem outras utilizações potenciais:
Expressões regulares compiladas. Todas as expressões regulares são analisadas e armazenadas num formato compilado. Pode armazenar expressões regulares compiladas em variáveis globais e, em seguida, usar a colocação em cache da app para reutilizar os objetos compilados entre pedidos.
Objetos GqlQuery. A string de consulta GQL é analisada quando o objeto GqlQuery é criado. A reutilização de um objeto GqlQuery com a associação de parâmetros e o método bind() é mais rápida do que a reconstrução do objeto de cada vez. Pode armazenar um objeto GqlQuery com a associação de parâmetros para os valores numa variável global e, em seguida, reutilizá-lo associando novos valores de parâmetros para cada pedido.
Ficheiros de configuração e de dados. Se a sua aplicação carregar e analisar dados de configuração a partir de um ficheiro, pode reter os dados analisados na memória para evitar ter de recarregar o ficheiro com cada pedido.
O script do controlador deve chamar main()
quando for importado. O App Engine espera que a importação do script chame main()
, pelo que o App Engine não o chama quando carrega o controlador de pedidos pela primeira vez num servidor.
O armazenamento em cache de apps com o main()
oferece uma melhoria significativa no tempo de resposta do controlador de CGI. Recomendamo-lo para todas as aplicações que usam CGI.
Registo
O servidor Web do App Engine captura tudo o que o script do controlador escreve no fluxo de saída padrão para a resposta ao pedido Web. Também captura tudo o que o script do controlador escreve no fluxo de erros padrão e armazena-o como dados de registo. A cada pedido é atribuído umrequest_id
, um identificador exclusivo a nível global com base na hora de início do pedido. Os dados de registo da sua aplicação podem ser vistos na Google Cloud consola Google Cloud através do Cloud Logging.
O ambiente de execução do Python do App Engine inclui compatibilidade especial com o módulo de registo da biblioteca padrão do Python para compreender conceitos de registo, como níveis de registo ("debug", "info", "warning", "error", "critical").
O ambiente
O ambiente de execução define automaticamente várias variáveis de ambiente. Pode definir mais emapp.yaml
. Das variáveis definidas automaticamente, algumas são especiais para o App Engine, enquanto outras fazem parte das normas WSGI ou CGI. O código Python pode aceder a estas variáveis através do dicionário os.environ
.
As seguintes variáveis de ambiente são específicas do App Engine:
CURRENT_VERSION_ID
: a versão principal e secundária da aplicação em execução atualmente, no formato "X.Y". O número da versão principal ("X") é especificado no ficheiroapp.yaml
da app. O número da versão secundária ("Y") é definido automaticamente quando cada versão da app é carregada para o App Engine. No servidor Web de desenvolvimento, a versão secundária é sempre "1".AUTH_DOMAIN
: o domínio usado para autenticar utilizadores com a API Users. As apps alojadas em appspot.com têm umAUTH_DOMAIN
degmail.com
e aceitam qualquer conta Google. As apps alojadas num domínio personalizado têm umAUTH_DOMAIN
igual ao domínio personalizado.INSTANCE_ID
: contém o ID da instância de front-end que processa um pedido. O ID é uma string hexadecimal (por exemplo,00c61b117c7f7fd0ce9e1325a04b8f0df30deaaf
). Um administrador com sessão iniciada pode usar o ID num URL:https://INSTANCE_ID-dot-VERSION_ID-dot-SERVICE_ID-dot-PROJECT_ID.REGION_ID.r.appspot.com
. O pedido é encaminhado para essa instância de front-end específica. Se a instância não conseguir processar o pedido, devolve um erro 503 imediato.
As seguintes variáveis de ambiente fazem parte das normas WSGI e CGI, com um comportamento especial no App Engine:
SERVER_SOFTWARE
: no servidor Web de desenvolvimento, este valor é "Development/X.Y", em que "X.Y" é a versão do tempo de execução. Quando executado no App Engine, este valor é "Google App Engine/X.Y.Z".
As variáveis de ambiente adicionais são definidas de acordo com a norma WSGI ou CGI. Para mais informações sobre estas variáveis, consulte a norma WSGI ou a norma CGI, conforme adequado.
Também pode definir variáveis de ambiente no app.yaml
ficheiro:
env_variables:
DJANGO_SETTINGS_MODULE: 'myapp.settings'
O controlador de pedidos webapp2 seguinte apresenta todas as variáveis de ambiente visíveis para a aplicação no navegador:
IDs de pedidos
No momento do pedido, pode guardar o ID do pedido, que é exclusivo desse pedido. O ID do pedido pode ser usado mais tarde para procurar os registos desse pedido no Cloud Logging.
O seguinte código de exemplo mostra como obter o ID do pedido no contexto de um pedido:
Forçar ligações HTTPS
Por motivos de segurança, todas as aplicações devem incentivar os clientes a estabelecer ligação através de
https
. Para instruir o navegador a preferir https
em vez de http
para uma determinada página ou domínio inteiro, defina o cabeçalho Strict-Transport-Security
nas suas respostas.
Por exemplo:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Para definir este cabeçalho para respostas geradas a partir do seu código, use a biblioteca flask-talisman
.
Processamento de trabalho assíncrono em segundo plano
O trabalho em segundo plano é qualquer trabalho que a sua app realiza para um pedido depois de ter enviado a resposta HTTP. Evite realizar trabalho em segundo plano na sua app e reveja o código para se certificar de que todas as operações assíncronas terminam antes de enviar a resposta.
Para tarefas de longa duração, recomendamos a utilização do Cloud Tasks. Com o Cloud Tasks, os pedidos HTTP são de longa duração e devolvem uma resposta apenas após a conclusão de qualquer trabalho assíncrono.