Java 8 Runtime Environment

Com o App Engine, é possível criar aplicativos da Web para usar a infraestrutura e os serviços escalonáveis do Google. O App Engine executa seu aplicativo da Web usando uma JVM Java 8 (em inglês). O App Engine invoca as classes de servlet do app para manipular solicitações e preparar respostas nesse ambiente.

A plataforma do App Engine oferece muitos serviços de API integrados que seu código pode chamar. Seu aplicativo também pode configurar tarefas programadas que são executadas em intervalos especificados.

Como especificar o ambiente de execução do Java 8 para o app

Para fazer com que seu app use o ambiente de execução do Java 8, adicione a seguinte linha ao seu arquivo appengine-web.xml:

<runtime>java8</runtime>

Observe que os aplicativos atuais do App Engine que antes usavam o ambiente de execução do Java 7 serão executados no ambiente de execução do Java 8 com essa simples alteração.

A API do App Engine para Java é representada pelo appengine-api-*.jar incluído no SDK do App Engine como parte do SDK do Cloud (em que * representa a versão da API e do SDK do App Engine).

Selecione a versão da API que seu aplicativo usa incluindo esse JAR no diretório WEB-INF/lib/ do aplicativo ou use o Maven para manipular dependências. Se uma nova versão do Java Runtime Environment for lançada, que inclua mudanças incompatíveis com os apps atuais, esse ambiente terá um novo número de versão principal.

Como usar o Maven para lidar com dependências

É possível usar o Maven para gerenciar todas as dependências. Por exemplo, esta entrada pom.xml inclui a API mais recente do App Engine (Rappengine-api-1.0-sdk) disponível na central do Maven:

<dependency>
    <groupId>com.google.appengine</groupId>
    <artifactId>appengine-api-1.0-sdk</artifactId>
    <version>1.9.82</version>
</dependency>

Sandbox

O ambiente de execução do Java do App Engine distribui solicitações de aplicativos em vários servidores da Web e impede que um aplicativo interfira em outro. Um aplicativo do App Engine não pode responder lentamente. Uma solicitação da Web para um aplicativo precisa ser manipulada dentro do tempo limite da solicitação. Os processos que excedem esse limite são finalizados para evitar a sobrecarga do servidor da web.

O único lugar em que os usuários podem gravar arquivos é o diretório /tmp. Os arquivos em /tmp consumirão a memória alocada para sua instância. Os arquivos armazenados nesse local só ficam disponíveis para essa instância, durante a vida útil dela.

A maneira usual de seu aplicativo receber arquivos de recursos é empacotar os arquivos necessários em seu aplicativo em WEB-INF e carregá-los do app usando Class.getResource(), ServletContext.getResource() ou métodos semelhantes. Por padrão, todos os arquivos no WAR são "arquivos de recursos". É possível excluir arquivos desse conjunto usando o arquivo appengine-web.xml.

Ordenação de JAR do carregador de classe

Às vezes, pode ser necessário redefinir a ordem em que as classes são verificadas nos arquivos JAR para resolver conflitos de nomes de classe. Nesses casos, a prioridade de carregamento pode ser concedida a arquivos JAR específicos adicionando um elemento <class-loader-config> contendo elementos <priority-specifier> ao arquivo appengine-web.xml. Exemplo:

<class-loader-config>
  <priority-specifier filename="mailapi.jar"/>
</class-loader-config>

Isso coloca "mailapi.jar" como o primeiro arquivo JAR no qual pesquisar classes, bloqueando-as no diretório war/WEB-INF/classes/.

Se vários arquivos JAR forem priorizados, será usada a ordem de carregamento original deles (entre eles). Quer dizer, a ordem dos elementos <priority-specifier> não importa.

Linhas de execução

Com o ambiente de execução do Java 8, é possível criar linhas de execução usando a API ThreadManager do App Engine e as APIs integradas do Java, por exemplo, new Thread(). Atualmente, se você quiser chamar APIs do App Engine (com.google.appengine.api.*), chame essas APIs de uma linha de execução de solicitação ou de uma linha de execução criada usando a API ThreadManager.

Com um aplicativo, é possível:

Se você criar um ThreadPoolExecutor com currentRequestThreadFactory(), shutdown() precisará ser chamado explicitamente antes que a solicitação de servlet seja concluída. Do contrário, a solicitação não será concluída e o servidor de aplicativos falhará. Observe que algumas bibliotecas podem criar ThreadPoolExecutors para você.

Um aplicativo pode realizar operações relativas à linha de execução atual, como thread.interrupt().

Cada solicitação é limitada a 50 linhas de execução de solicitação de API do App Engine simultâneas.

Ao usar linhas de execução, use objetos de simultaneidade de alto nível (em inglês), como Executor e Runnable. Eles cuidam de detalhes sutis, mas importantes, da simultaneidade, como interrupções e programação e contabilidade (links em inglês).

O número máximo de threads simultâneos em segundo plano criados pela API App Engine é de 10 por instância. Esse limite não se aplica a segmentos comuns do Java não relacionados à API App Engine.

Ferramentas

IDEs compatíveis

Com o Cloud Tools for Eclipse, novos assistentes de projeto e configurações de depuração são adicionados ao ambiente de desenvolvimento integrado do Eclipse (em inglês) em projetos do App Engine. Você implanta seus projetos do App Engine dinamicamente na produção de dentro do Eclipse.

Com o Cloud Tools for IntelliJ, é possível executar e depurar aplicativos do App Engine no IntelliJ IDEA (em inglês). Os projetos do App Engine podem ser implantados dinamicamente na produção sem sair do ambiente de desenvolvimento integrado.

Ferramentas de compilação compatíveis

Para acelerar o processo de desenvolvimento, use os plug-ins do App Engine para Apache Maven ou Gradle:

Servidor de desenvolvimento local

O servidor de desenvolvimento executa seu aplicativo no computador local de desenvolvimento e testes. O servidor simula os serviços do Datastore. O servidor de desenvolvimento também pode gerar configurações para índices do Datastore com base nas consultas que o app realiza durante o teste.

AppCfg

O AppCfg está incluído no SDK autônomo do App Engine para Java. Trata-se de uma ferramenta multifuncional que manipula a interação da linha de comando com seu aplicativo em execução no App Engine. O AppCfg pode fazer upload do aplicativo para o App Engine ou apenas atualizar a configuração do índice do Datastore, permitindo a criação de novos índices antes da atualização do código. Ele também faz o download dos dados de registro do app para que você analise o desempenho do app usando ferramentas próprias.

Simultaneidade e latência

A latência do seu aplicativo tem o maior impacto no número de instâncias necessárias para disponibilizar o tráfego. Se você processa solicitações rapidamente, uma única instância pode manipular muitas solicitações.

As instâncias com linha de execução única podem manipular uma solicitação simultânea. Portanto, há uma relação direta entre a latência e o número de solicitações que podem ser manipuladas na instância por segundo. Por exemplo, a latência de 10 ms é igual a 100 solicitações por segundo por instância.

As instâncias com vários threads podem processar várias solicitações simultâneas. Portanto, há uma relação direta entre a CPU consumida e o número de solicitações por segundo.

Os apps Java são compatíveis com solicitações simultâneas, portanto, uma única instância pode manipular novas solicitações enquanto aguarda a conclusão de outras. A simultaneidade reduz muito o número de instâncias exigidas pelo app, mas você precisa projetar seu app para várias linhas de execução.

Por exemplo, se uma instância B4 (aproximadamente 2,4 GHz) consome 10 milhões de ciclos por solicitação, é possível processar 240 solicitações por segundo por instância. Se ela consome 100 milhões de ciclos/solicitação, você pode processar 24 solicitações/segundo/instância. Esses números representam o caso ideal, mas são bem realistas quanto ao que é possível realizar em uma instância.