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>

O arquivo appengine-api.jar incluído na Google Cloud CLI em platform/google_appengine/google/appengine/tools/java/lib/impl/appengine-api.jar representa a API App Engine para Java. Também é possível acessar esse arquivo usando o repositório Maven que lista todas as versões.

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></version>
</dependency>

Sandbox

O ambiente de execução do Java App Engine distribui pedidos de aplicativos em vários servidores da Web e impede que um aplicativo interfira com 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. Por 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 segmentos de solicitação simultâneos à App Engine API.

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 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.

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/segundo.

Os aplicativos Java são compatíveis com solicitações simultâneas, portanto, uma única instância pode processar novas solicitações enquanto aguarda que outras sejam concluídas. A simultaneidade reduz significativamente o número de instâncias que seu aplicativo requer, mas você precisa projetar seu aplicativo para vários threads.

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

Versões do Java do App Engine

Todos os artefatos lançados que começam com a versão 2.x.x usam o mecanismo de lançamento de código aberto. Os artefatos lançados que começam com a versão 1.9.9xx ou anterior usam o sistema de compilação interno. Consulte o repositório do GitHub para mais detalhes.

Variáveis de ambiente

As seguintes variáveis de ambiente são definidas pelo ambiente de execução:

Variável de ambiente Descrição
GAE_APPLICATION O ID do aplicativo do App Engine. Esse ID tem o prefixo "region code~", como "e~" para aplicativos implantados na Europa.
GAE_DEPLOYMENT_ID O ID da implantação atual.
GAE_ENV O ambiente do App Engine. Defina como standard.
GAE_INSTANCE O ID da instância em que o serviço é executado no momento.
GAE_RUNTIME O ambiente de execução especificado no seu arquivo app.yaml.
GAE_SERVICE O nome do serviço especificado no seu arquivo app.yaml. Se nenhum nome de serviço for especificado, ele será definido como default.
GAE_VERSION O rótulo da versão atual do serviço.
GOOGLE_CLOUD_PROJECT O ID do projeto do Google Cloud associado ao aplicativo.
PORT A porta que recebe solicitações HTTP.

É possível definir variáveis de ambiente adicionais no arquivo app.yaml, mas os valores acima não podem ser modificados.