Java Runtime Environment 8

Con App Engine, puedes compilar aplicaciones web que usan la infraestructura escalable y los servicios de Google. App Engine ejecuta tu aplicación web con una JVM de Java 8. App Engine invoca las clases de servlet de tu app para administrar las solicitudes y preparar respuestas en este entorno.

La plataforma de App Engine brinda muchos servicios de la API que tu código puede llamar. Tu aplicación también puede configurar tareas programadas que se ejecutan en intervalos específicos.

Especifica el entorno de ejecución de Java 8 para tu app

Para que tu app use el entorno de ejecución de Java 8, agrega la siguiente línea de código al archivo appengine-web.xml:

<runtime>java8</runtime>

El archivo appengine-api.jar incluido en Google Cloud CLI en platform/google_appengine/google/appengine/tools/java/lib/impl/appengine-api.jar representa la API de App Engine para Java. También puedes acceder a este archivo a través del repositorio de Maven, que enumera todas las versiones.

Incluye este archivo JAR en el directorio WEB-INF/lib/ de la aplicación para seleccionar la versión de la API que usa, o usa Maven para administrar las dependencias. Si se lanza una nueva versión del entorno de ejecución de Java que incorpora cambios que no son compatibles con las apps existentes, ese entorno tendrá un nuevo número de versión principal.

Cómo usar Maven para manejar dependencias

Puedes usar Maven para gestionar todas las dependencias. Por ejemplo, esta entrada pom.xml incluye la última API de App Engine (Rappengine-api-1.0-sdk) disponible en Maven Central:

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

Zona de pruebas

El entorno de ejecución de Java de App Engine distribuye solicitudes de aplicaciones en varios servidores web, lo cual impide que una aplicación interfiera en otra. Una app de App Engine no debe responder con lentitud. Una solicitud web a una aplicación debe controlarse dentro del límite de tiempo de espera de la solicitud. Los procesos que exceden este límite de respuesta se finalizan para evitar sobrecargar el servidor web.

Ten en cuenta que el directorio /tmp es el único lugar en el que los usuarios pueden escribir archivos. Los archivos en /tmp consumirán la memoria asignada a tu instancia. Los archivos almacenados en esta ubicación solo están disponibles para esta instancia y solo desde el principio de esta instancia específica.

La forma habitual en la que tu aplicación obtiene archivos de recursos es empaquetar los archivos que necesitas con tu aplicación en WEB-INF y, a continuación, cargarlos desde la app con Class.getResource(), ServletContext.getResource() o métodos similares. De forma predeterminada, todos los archivos en el WAR son “archivos de recursos”. Puedes excluir archivos de este conjunto con el archivo appengine-web.xml.

Orden del cargador de clase JAR

A veces, puede ser necesario volver a definir el orden en el que los archivos JAR se analizan en busca de clases para resolver conflictos entre los nombres de clase. En estos casos, puedes otorgar la prioridad de carga a archivos JAR específicos si agregas un elemento <class-loader-config> que contenga elementos <priority-specifier> en el archivo appengine-web.xml. Por ejemplo:

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

Esto coloca a “mailapi.jar” como el primer archivo JAR en el que se buscarán clases, excepto aquellas en el directorio war/WEB-INF/classes/.

Si se priorizan varios archivos JAR, se usará su orden de carga original (uno con respecto al otro). En otras palabras, el orden para los elementos <priority-specifier> no importa.

Subprocesos

Con el entorno de ejecución de Java 8, puedes crear subprocesos a través de la API de ThreadManager de App Engine y las API incorporadas de Java, como new Thread(). Por el momento, si quieres llamar a las API de App Engine (com.google.appengine.api.*), debes hacerlo desde un subproceso de solicitud o un subproceso creado con la API de ThreadManager.

Una aplicación puede realizar lo siguiente:

Si creas ThreadPoolExecutor con currentRequestThreadFactory(), debes llamar de forma explícita a shutdown() antes de que se complete la solicitud de servlet. Si no lo haces, la solicitud no se completará y el servidor de aplicaciones fallará. Ten en cuenta que algunas bibliotecas pueden crear ThreadPoolExecutors por ti.

Una aplicación puede realizar varias operaciones en el subproceso actual, como thread.interrupt().

Cada solicitud está limitada a 50 subprocesos de solicitud de API de App Engine simultáneos.

Cuando uses subprocesos, usa objetos de nivel alto de simultaneidad, como Executor y Runnable. Estos se ocupan de muchos de los detalles sutiles, pero importantes, de la simultaneidad, como las interrupciones y la programación y contabilidad.

La cantidad máxima de subprocesos en segundo plano simultáneos creados por la API de App Engine es 10 por instancia. (Este límite no se aplica a los subprocesos de Java normales no relacionados con la API de App Engine).

Herramientas

IDE compatibles

Cloud Tools for IntelliJ te permite ejecutar y depurar aplicaciones de App Engine en IntelliJ IDEA. Puedes implementar proyectos de App Engine en vivo a producción sin salir del IDE.

Herramientas de compilación compatibles

Para acelerar el proceso de desarrollo, puedes usar los complementos de App Engine para Apache Maven o Gradle:

Servidor de desarrollo local

El servidor de desarrollo ejecuta la aplicación en tu computadora local para el desarrollo y las pruebas. El servidor simula los servicios de Datastore. El servidor de desarrollo también puede generar la configuración de los índices de Datastore según las consultas que realiza la app durante las pruebas.

Simultaneidad y latencia

La latencia de tu aplicación tiene el mayor impacto en la cantidad de instancias necesarias para entregar tu tráfico. Si procesas las solicitudes con rapidez, una única instancia puede manejar muchas solicitudes.

Las instancias de subprocesos únicos pueden controlar muchas solicitudes simultáneas. Por lo tanto, hay una relación directa entre la latencia y la cantidad de solicitudes que se pueden manejar en la instancia por segundo. Por ejemplo, 10 ms de latencia equivalen a 100 solicitudes por segundo por instancia.

Las instancias de subprocesos múltiples pueden controlar muchas solicitudes simultáneas. Por lo tanto, existe una relación directa entre la CPU consumida y la cantidad de solicitudes por segundo.

Las aplicaciones de Java admiten solicitudes simultáneas, de modo que una sola instancia puede manejar solicitudes nuevas mientras espera a que las demás se completen. La simultaneidad reduce en gran medida la cantidad de instancias que requiere tu aplicación, pero debes diseñarla para multiprocesos.

Por ejemplo, si una instancia B4 (un aproximado de 2.4 GHz) consume 10 Mcycles por solicitud, puedes procesar 240 solicitudes por segundo por instancia. Si consume 100 Mcycles por solicitud, puedes procesar 24 solicitudes por segundo por instancia. Estos números son el caso ideal, pero son bastante realistas en términos de lo que puedes lograr en una instancia.

Versiones de Java de App Engine

Todos los artefactos publicados que empiezan con la versión 2.x.x usan el mecanismo de actualización de código abierto. Los artefactos publicados que empiezan con la versión 1.9.9xx o anteriores usan el sistema de compilación interno. Consulta el repositorio de GitHub para obtener más detalles.

Variables de entorno

El entorno de ejecución configura las siguientes variables del entorno:

Variable de entorno Descripción
GAE_APPLICATION ID de tu aplicación de App Engine. Este ID tiene el prefijo “region code~”, como “e~”, para aplicaciones implementadas en Europa.
GAE_DEPLOYMENT_ID ID de la implementación actual.
GAE_ENV Entorno de App Engine. Se define en standard.
GAE_INSTANCE ID de la instancia en la que se está ejecutando tu servicio.
GAE_RUNTIME Entorno de ejecución especificado en el archivo app.yaml.
GAE_SERVICE Nombre de servicio especificado en el archivo app.yaml. Si no se especifica un nombre de servicio, se asigna default.
GAE_VERSION Etiqueta de la versión actual de tu servicio.
GOOGLE_CLOUD_PROJECT ID del proyecto de Google Cloud asociado a tu aplicación.
PORT Puerto que recibe las solicitudes HTTP.

Puedes definir variables de entorno adicionales en tu archivo app.yaml, pero los valores anteriores no se pueden anular.