Pode usar pedidos de preparação para reduzir a latência de pedidos e respostas durante o período em que o código da sua app está a ser carregado para uma instância recém-criada.
O App Engine precisa frequentemente de carregar o código da sua app numa instância nova. O carregamento de uma instância pode ocorrer nas seguintes situações:
- Quando reimplementa uma versão da sua app.
- Quando são criadas novas instâncias devido à carga de pedidos que excede a capacidade do conjunto atual de instâncias em execução.
- Quando ocorrem manutenção e reparações da infraestrutura subjacente ou do hardware físico.
Carregar o código da sua app para uma nova instância pode resultar em pedidos de carregamento. Os pedidos de carregamento podem resultar num aumento da latência dos pedidos para os seus utilizadores, mas pode evitar esta latência através de pedidos de preparação. Os pedidos de preparação carregam o código da sua app numa nova instância antes de quaisquer pedidos em direto chegarem a essa instância.
Se os pedidos de preparação estiverem ativados para a sua aplicação, o App Engine tenta detetar quando a aplicação precisa de uma nova instância e inicia um pedido de preparação para inicializar uma nova instância. No entanto, estas tentativas de deteção não funcionam em todos os casos. Como resultado, pode encontrar pedidos de carregamento, mesmo que os pedidos de preparação estejam ativados na sua app. Por exemplo, se a sua app não estiver a publicar tráfego, o primeiro pedido à app será sempre um pedido de carregamento e não um pedido de preparação.
Os pedidos de preparação usam horas de instância como qualquer outro pedido para a sua aplicação do App Engine. Na maioria dos casos em que os pedidos de aquecimento estão ativados, não vai notar um aumento nas horas de instância porque a sua aplicação está simplesmente a ser inicializada num pedido de aquecimento em vez de num pedido de carregamento. A utilização de horas da instância pode aumentar se decidir fazer mais trabalho, como a colocação em cache prévia durante um pedido de aquecimento. Se definir
min_idle_instances
para um valor superior a 0
, pode encontrar pedidos de preparação quando essas instâncias
são iniciadas pela primeira vez, mas permanecem disponíveis após esse período.
Ativar pedidos de preparação
Os pedidos de aquecimento são usados pelo programador do App Engine, que
controla a criação de uma escala automática de instâncias com base na configuração fornecida pelo utilizador.
No tempo de execução Java do App Engine, os pedidos de preparação estão ativados por predefinição e, por isso, o App Engine envia pedidos GET
para /_ah/warmup
, o que lhe permite responder e inicializar o código da sua aplicação conforme necessário. Pode responder aos pedidos de preparação através de um dos seguintes métodos:
- Usar um servlet
<load-on-startup>
- A forma mais fácil de fornecer lógica de preparação é marcar os seus próprios servlets como
<load-on-startup>
no ficheiro de configuraçãoweb.xml
. - Usar um
ServletContextListener
- Permite-lhe executar uma lógica personalizada antes de qualquer um dos seus servlets ser invocado pela primeira vez, quer através de um pedido de preparação ou de um pedido de carregamento.
- Usar um servlet de preparação personalizado
- A utilização de um servlet de preparação personalizado invoca o método
service
do servlet apenas durante um pedido de preparação e não durante pedidos de carregamento.
Pode ter de implementar o seu próprio controlador para /_ah/warmup
, consoante
qual destes métodos escolher.
Antes de começar
Quando os pedidos de preparação estão ativados, o programador inicia instâncias quando determina que são necessárias mais instâncias. O programador usa pedidos de aquecimento para iniciar a sua app, pelo que vê registos mesmo que a app não processe esses pedidos de aquecimento.
A mensagem seguinte indica pedidos de preparação nos registos /_ah/warmup
:
This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application.
Tenha em atenção que não é garantido que os pedidos de preparação sejam chamados. Em algumas situações, são enviados pedidos de carregamento. Por exemplo, se a instância for a primeira a ser iniciada ou se houver um aumento acentuado no tráfego. No entanto, será feito um esforço para enviar pedidos a instâncias já aquecidas se os pedidos de aquecimento estiverem ativados.
No Java 8, os pedidos de preparação estão ativados por predefinição. Para as ativar,
adicione - warmup
à diretiva
inbound_services
em appengine-web.xml
. Uma vez que, por predefinição, as inicializações estão ativadas, só tem de as ativar explicitamente se tiver implementado anteriormente uma aplicação com pedidos de inicialização desativados no appengine-web.xml
.
Se for este o caso, tem de definir o valor de <warmup-requests-enabled>
como true
e, em seguida, reimplementar.
Usar um servlet <load-on-startup>
A forma mais fácil de fornecer lógica de preparação é marcar os seus próprios servlets como <load-on-startup>
em web.xml
. Este método não requer alterações ao código da aplicação e inicializa todos os servlets especificados quando a aplicação é inicializada.
No ficheiro web.xml
, para os servlets que quer carregar no arranque, adicione o elemento <load-on-startup>1</load-on-startup>
ao elemento <servlet>
. Por exemplo:
<servlet>
<servlet-name>my-servlet</servlet-name>
<servlet-class>com.company.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Estas linhas carregam a classe de servlet especificada e invocam o método init()
do servlet. O pedido de aquecimento inicializa os servlets especificados antes de processar
quaisquer pedidos em direto. No entanto, se não existir um pedido de preparação, os servlets especificados em <load-on-startup>
são registados no primeiro pedido a uma nova instância, o que resulta num pedido de carregamento. Conforme referido anteriormente, o App Engine pode não emitir um pedido de preparação sempre que a sua aplicação precisar de uma nova instância.
Usar um ServletContextListener
Se tiver uma lógica personalizada que quer executar antes de qualquer um dos seus servlets ser invocado:
Registe um
ServletContextListener
no seu ficheiroweb.xml
.<listener> <listener-class>com.company.MyListener</listener-class> </listener>
Forneça uma classe juntamente com o código do servlet e do filtro:
public class MyListener implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { // This will be invoked as part of a warmup request, or // the first user request if no warmup request was invoked. } public void contextDestroyed(ServletContextEvent event) { // App Engine does not currently invoke this method. } }
O ServletContextListener
é executado durante um pedido de preparação. Se não existir um pedido de aquecimento, este é executado no primeiro pedido a uma nova instância. Isto pode resultar em pedidos de carregamento.
Usar um servlet de preparação personalizado
O servlet de preparação personalizado invoca o método service
do servlet apenas durante um pedido de preparação. Ao colocar uma lógica dispendiosa num servlet de preparação personalizado, pode evitar o aumento dos tempos de carregamento nos pedidos de carregamento.
Para criar um servlet de preparação personalizado, basta substituir a definição do servlet incorporado para _ah_warmup
em web.xml
:
<servlet>
<servlet-name>_ah_warmup</servlet-name>
<servlet-class>com.company.MyWarmupServlet</servlet-class>
</servlet>