Como são processados os pedidos

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.

O tempo de execução do Go para o App Engine usa o pacote http padrão como uma interface entre o seu programa Go e os servidores do App Engine. Quando o App Engine recebe um pedido Web para a sua aplicação, invoca o http.Handler associado ao URL do pedido.

O exemplo seguinte é uma app Go completa que produz uma string HTML codificada para o utilizador:


// Sample helloworld is an App Engine app.
package main

import (
	"fmt"
	"log"
	"net/http"
	"os"
)



func main() {
	http.HandleFunc("/", indexHandler)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
		log.Printf("Defaulting to port %s", port)
	}

	log.Printf("Listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}



// indexHandler responds to requests with our greeting.
func indexHandler(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path != "/" {
		http.NotFound(w, r)
		return
	}
	fmt.Fprint(w, "Hello, World!")
}

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. Para os controladores de pedidos do Go, o processo é interrompido e o ambiente de tempo de execução devolve um erro interno do servidor HTTP 500 ao cliente.

Responses

O App Engine chama o controlador com um Request e um ResponseWriter e, em seguida, aguarda que o controlador escreva no ResponseWriter e retorne. Quando o controlador devolve, os dados no buffer interno do ResponseWriter são enviados para o utilizador.

Isto é praticamente o mesmo que quando escreve programas Go normais que usam o pacote 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

Para as respostas devolvidas pelo seu código, o App Engine comprime os dados na resposta se ambas as seguintes condições forem verdadeiras:

  • O pedido contém o cabeçalho Accept-Encoding que inclui gzip como valor.
  • A resposta contém dados baseados em texto, como HTML, CSS ou JavaScript.

Para respostas devolvidas por um controlador de ficheiros estáticos ou diretórios do App Engine, os dados de resposta são comprimidos se todas as seguintes condições forem verdadeiras:

  • O pedido inclui Accept-Encoding com gzip como um dos respetivos valores.
  • O cliente é capaz de receber os dados de resposta num formato comprimido. O front-end da Google mantém uma lista de clientes que se sabe terem problemas com respostas comprimidas. Estes clientes não recebem dados comprimidos de controladores estáticos na sua app, mesmo que os cabeçalhos de pedidos contenham Accept-Encoding: gzip.
  • A resposta contém dados baseados em texto, como HTML, CSS ou JavaScript.

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 e User-Agent como gzip.

  • Se um pedido não especificar gzip no cabeçalho Accept-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 como public 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 diretiva Cache-Control private ou no-store. Se não definir este cabeçalho em app.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 resposta Vary: Accept, Accept-Encoding, Origin ou X-Origin

    Devido ao potencial de elevada cardinalidade, os dados não são colocados em cache para outros valores de Vary.

    Por exemplo:

    1. Especifique o seguinte cabeçalho da resposta:

      Vary: Accept-Encoding

    2. 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çalho Accept-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).

    3. 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çalho Accept-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:

    1. Não especifica o cabeçalho da resposta Vary: Accept-Encoding.
    2. Um pedido contém o cabeçalho Accept-Encoding: gzip e a versão comprimida com gzip dos dados de resposta é colocada em cache.
    3. 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.

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 qualquer conteúdo estático publicado pela sua app, adicione o cabeçalho aos controladores de ficheiros e diretórios estáticos da app.

Para definir este cabeçalho para respostas geradas a partir do seu código, use o pacote secureheader.

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.