Entorno de tiempo de ejecución de Java 8

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

La plataforma App Engine proporciona muchos servicios de API integrados a los que puede llamar tu código. Tu aplicación también puede configurar tareas programadas que se ejecuten a intervalos especificados.

Especificar el entorno de ejecución de Java 8 para tu aplicación

Para que tu aplicación use el tiempo de ejecución de Java 8, añade la siguiente línea 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 appengine-api.jar representa la API de App Engine para Java. También puedes acceder a este archivo mediante el repositorio Maven, que incluye todas las versiones.

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

Usar Maven para gestionar las dependencias

Puedes usar Maven para gestionar todas las dependencias. Por ejemplo, esta entrada de pom.xml incluye la API de App Engine más reciente (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>

El entorno aislado

El entorno de ejecución de Java de App Engine distribuye las solicitudes de las aplicaciones entre varios servidores web e impide que una aplicación interfiera con otra. Una aplicación de App Engine no debe responder lentamente. Una solicitud web a una aplicación debe gestionarse dentro del límite de tiempo de espera de la solicitud. Los procesos que superen este límite se cancelarán para evitar que se sobrecargue el servidor web.

Ten en cuenta que el único lugar en el que los usuarios pueden escribir archivos es el directorio /tmp. Los archivos de /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 durante el tiempo de vida de esta instancia específica.

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

Orden de JAR del cargador de clases

En ocasiones, puede ser necesario redefinir el orden en el que se analizan los archivos JAR para buscar clases con el fin de resolver conflictos entre nombres de clases. En estos casos, se puede conceder prioridad de carga a archivos JAR específicos añadiendo 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>

De esta forma, "mailapi.jar" se convierte en el primer archivo JAR en el que se buscarán clases, excepto en el directorio war/WEB-INF/classes/.

Si se priorizan varios archivos JAR, se usará su orden de carga original (con respecto a los demás). Es decir, el orden de los elementos <priority-specifier> no importa.

Conversaciones

Con el entorno de ejecución de Java 8, puedes crear subprocesos con la API ThreadManager de App Engine y las APIs integradas de Java, como new Thread(). Actualmente, si quieres llamar a las APIs de App Engine (com.google.appengine.api.*), debes hacerlo desde un hilo de solicitud o desde un hilo creado con la API ThreadManager.

Una aplicación puede

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

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

Cada solicitud está limitada a 50 subprocesos de solicitudes simultáneas a la API de App Engine.

Cuando uses hilos, utiliza objetos de simultaneidad de alto nivel, como Executor y Runnable. Se encargan de muchos de los detalles sutiles pero importantes de la simultaneidad, como las interrupciones y la programación y la contabilidad.

El número máximo de subprocesos en segundo plano simultáneos creados por la API de App Engine es de 10 por instancia. Este límite no se aplica a los hilos de Java normales que no están relacionados con la API de App Engine.

Herramientas

IDEs compatibles

Cloud Tools for IntelliJ te permite ejecutar y depurar aplicaciones de App Engine en IntelliJ IDEA. Puedes desplegar tus proyectos de App Engine en 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 tu aplicación en tu ordenador 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 en función de las consultas que realice la aplicación durante las pruebas.

Simultaneidad y latencia

La latencia de tu aplicación es el factor que más influye en el número de instancias necesarias para atender tu tráfico. Si procesas las solicitudes rápidamente, una sola instancia puede gestionar muchas solicitudes.

Las instancias de un solo subproceso pueden gestionar una solicitud simultánea. Por lo tanto, existe una relación directa entre la latencia y el número de solicitudes que se pueden gestionar en la instancia por segundo. Por ejemplo, una latencia de 10 ms equivale a 100 solicitudes por segundo y por instancia.

Las instancias multihilo pueden gestionar muchas solicitudes simultáneas. Por lo tanto, existe una relación directa entre la CPU consumida y el número de solicitudes por segundo.

Las aplicaciones Java admiten solicitudes simultáneas, por lo que una sola instancia puede gestionar nuevas solicitudes mientras espera que se completen otras. La simultaneidad reduce significativamente el número de instancias que necesita tu aplicación, pero debes diseñar tu aplicación para que sea multihilo.

Por ejemplo, si una instancia B4 (aproximadamente 2,4 GHz) consume 10 Mciclos/solicitud, puedes procesar 240 solicitudes/segundo/instancia. Si consume 100 Mciclos por solicitud, puedes procesar 24 solicitudes por segundo y por instancia. Estas cifras son las ideales, pero son bastante realistas en cuanto a lo que puedes conseguir en una instancia.

Versiones de Java de App Engine

Todos los artefactos publicados que empiezan por la versión 2.x.x usan el mecanismo de publicación de código abierto. Los artefactos publicados que empiezan por la versión 1.9.9xx o una anterior usan el sistema de compilación interno. Consulta el repositorio de GitHub para obtener más información.

Variables de entorno

El tiempo de ejecución define las siguientes variables de entorno:

Variable de entorno Descripción
GAE_APPLICATION El ID de tu aplicación de App Engine. Este ID tiene el prefijo "region code~", como "e~" en el caso de las aplicaciones desplegadas en Europa.
GAE_DEPLOYMENT_ID ID de la implementación actual.
GAE_ENV El entorno de App Engine. Su valor debe ser standard.
GAE_INSTANCE El ID de la instancia en la que se está ejecutando tu servicio.
GAE_RUNTIME El tiempo de ejecución especificado en el archivo app.yaml.
GAE_SERVICE El nombre del servicio especificado en el archivo app.yaml. Si no se especifica ningún nombre de servicio, se le asigna el valor default.
GAE_VERSION La etiqueta de la versión actual de tu servicio.
GOOGLE_CLOUD_PROJECT El ID de proyecto Google Cloud asociado a tu aplicación.
PORT El puerto que recibe solicitudes HTTP.

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