Crear perfiles de aplicaciones Java

En esta página se describe cómo modificar tu aplicación Java para capturar datos de creación de perfiles y enviarlos a tu proyecto de Google Cloud. Para obtener información general sobre la creación de perfiles, consulta el artículo Conceptos de la creación de perfiles.

.

Tipos de perfiles de Java:

  • Tiempo de CPU
  • Montículo (requiere Java 11 o el entorno estándar de App Engine; está inhabilitado de forma predeterminada)
  • Tiempo real (no disponible en el entorno estándar de App Engine para Java 8)

Versiones del lenguaje Java admitidas:

  • JVMs basadas en HotSpot (incluido Oracle JDK y algunas compilaciones de OpenJDK) para Java 8, 11 o versiones posteriores.

Versiones compatibles del agente de creación de perfiles:

  • Se admite la versión más reciente del agente. Por lo general, no se admiten las versiones que tengan más de un año. Te recomendamos que uses la versión más reciente del agente.

Sistemas operativos compatibles:

  • Linux. La creación de perfiles de aplicaciones Java es compatible con los kernels de Linux cuya biblioteca C estándar se implementa con glibc o con musl. Para obtener información sobre la configuración específica de los kernels de Linux Alpine, consulta Ejecutar en Linux Alpine.

Entornos admitidos:

Habilitar la API Profiler

Antes de usar el agente de creación de perfiles, asegúrate de que la API Profiler subyacente esté habilitada. Puedes comprobar el estado de la API y habilitarla si es necesario mediante la CLI de Google Cloud o la consola de Google Cloud :

CLI de gcloud

  1. Si aún no has instalado Google Cloud CLI en tu estación de trabajo, consulta la documentación de Google Cloud CLI.

  2. Ejecuta el siguiente comando:

    gcloud services enable cloudprofiler.googleapis.com
    

Para obtener más información, consulta gcloud services.

Google Cloud consola

  1. Enable the required API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  2. Si se muestra API habilitada, significa que la API ya está habilitada. Si no es así, haz clic en el botón Habilitar.

Asignar un rol de gestión de identidades y accesos a una cuenta de servicio

Si vas a implementar tu aplicación en recursos de Google Cloud y usas la cuenta de servicio predeterminada sin haber modificado las concesiones de roles de esa cuenta, puedes saltarte esta sección.

Si haces alguna de las siguientes acciones, debes conceder a la cuenta de servicio el rol de gestión de identidades y accesos Agente de Cloud Profiler (roles/cloudprofiler.agent):

  1. Estás usando la cuenta de servicio predeterminada, pero has modificado sus concesiones de roles.
  2. Estás usando una cuenta de servicio creada por un usuario.
  3. Si usas Workload Identity, concede el rol Agente de Cloud Profiler a la cuenta de servicio de Kubernetes.

Para asignar un rol de gestión de identidades y accesos a una cuenta de servicio, puedes usar laGoogle Cloud consola o la CLI de Google Cloud. Por ejemplo, puedes usar el comando gcloud projects add-iam-policy-binding:

gcloud projects add-iam-policy-binding GCP_PROJECT_ID \
    --member serviceAccount:MY_SVC_ACCT_ID@GCP_PROJECT_ID.iam.gserviceaccount.com \
    --role roles/cloudprofiler.agent

Antes de usar el comando anterior, sustituye lo siguiente:

  • GCP_PROJECT_ID: tu ID de proyecto.
  • MY_SVC_ACCT_ID: el nombre de tu cuenta de servicio.

Para obtener información detallada, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

Instalar el agente de Profiler

Compute Engine

  1. Crea un directorio de instalación, por ejemplo, /opt/cprof, para el agente de Profiler:

     sudo mkdir -p /opt/cprof

  2. Descarga el archivo del agente del repositorio storage.googleapis.com y descomprímelo en el directorio de instalación:

    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | sudo tar xzv -C /opt/cprof

GKE

Modifica Dockerfile para crear un directorio de instalación del agente de Profiler, descarga el archivo del agente y, a continuación, extrae el archivo en el directorio de instalación.

Linux (biblioteca C basada en glibc):

Usa el siguiente comando de instalación:

RUN mkdir -p /opt/cprof && \
  wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
  | tar xzv -C /opt/cprof

Linux Alpine (biblioteca C basada en musl):

Usa el siguiente comando de instalación:

wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent_alpine.tar.gz \
| tar xzv -C /opt/cprof

Entorno flexible

Si usas la imagen base del tiempo de ejecución de Java 8 de Google o la imagen base del tiempo de ejecución de Java 9 o Jetty 9, el agente de Profiler estará preinstalado, por lo que no tendrás que seguir ningún paso adicional para instalarlo.

En el resto de las imágenes base, debes instalar el agente. Por ejemplo, el siguiente Dockerfile contiene las instrucciones para usar la imagen openjdk:11-slim, instalar el agente Profiler y definir los parámetros predeterminados que se usarán al iniciar la aplicación:

FROM openjdk:11-slim

COPY . .
RUN  apt-get update \
     && apt-get install wget \
     && rm -rf /var/lib/apt/lists/*

RUN mkdir -p /opt/cprof && \
    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | tar xzv -C /opt/cprof

CMD ["java", "-agentpath:/opt/cprof/profiler_java_agent.so=OPTION1,OPTION2", "-jar", "PATH_TO_YOUR_JAR_FILE"]

Para usar este Dockerfile con el entorno flexible de App Engine, debes hacer lo siguiente:

  • Sustituye OPTION1 y OPTION2 por los valores de configuración del agente que necesites para tu aplicación y sustituye PATH_TO_YOUR_JAR_FILE por la ruta de tu archivo JAR.
  • Coloca el archivo Dockerfile en el mismo directorio que el archivo app.yaml.
  • Modifica el archivo app.yaml para especificar un tiempo de ejecución personalizado. Para obtener más información, consulta Crear tiempos de ejecución personalizados.

Entorno estándar

Cuando usas el entorno de tiempo de ejecución de Java, el agente de Profiler está preinstalado, por lo que no tienes que seguir ningún paso adicional para instalarlo. En Java 11 y versiones posteriores, está preinstalado en /opt/cprof.

Fuera de Google Cloud

  1. Crea un directorio de instalación, por ejemplo, /opt/cprof, para el agente de Profiler:

     sudo mkdir -p /opt/cprof

  2. Descarga el archivo del agente del repositorio storage.googleapis.com y descomprímelo en el directorio de instalación:

    wget -q -O- https://storage.googleapis.com/cloud-profiler/java/latest/profiler_java_agent.tar.gz \
    | sudo tar xzv -C /opt/cprof

Para enumerar todas las versiones del agente disponibles para descargar, ejecuta el siguiente comando:

gcloud storage ls gs://cloud-profiler/java/cloud-profiler-*

La respuesta del comando es similar a la siguiente:

gs://cloud-profiler/java/cloud-profiler-java-agent_20191014_RC00.tar.gz
gs://cloud-profiler/java/cloud-profiler-java-agent_20191021_RC00.tar.gz
gs://cloud-profiler/java/cloud-profiler-java-agent_20191028_RC00.tar.gz

Para descargar una versión específica del agente, pasa su URL al comando de descarga. Por ejemplo, para descargar el agente creado el 28 de octubre del 2019, usarías la siguiente instrucción:

wget -q -O- https://storage.googleapis.com/cloud-profiler/java/cloud-profiler-java-agent_20191028_RC00.tar.gz \
  | sudo tar xzv -C /opt/cprof

La versión del agente se registra durante su inicialización.

Cargar el agente de Profiler

Para crear un perfil de tu aplicación, inicia Java como lo harías normalmente para ejecutar tu programa, pero especifica las opciones de configuración del agente. Especifica la ruta a la biblioteca del agente y puedes transferir opciones a la biblioteca.

En el entorno estándar de App Engine, el agente se carga y se configura automáticamente. Ve a la sección Empezar el programa para obtener información sobre cómo configurar e iniciar el programa.

Configuración del agente

Para configurar el agente de creación de perfiles, incluye la marca -agentpath al iniciar la aplicación:

 -agentpath:INSTALL_DIR/profiler_java_agent.so=OPTION1,OPTION2,OPTION3

En esta expresión, INSTALL_DIR es la ruta al agente de creación de perfiles, mientras que OPTION1, OPTION2 y OPTION3 son opciones de configuración del agente. Por ejemplo, si sustituyes OPTION1 por -cprof_service=myapp en la expresión anterior, el nombre del servicio será myapp. No hay ninguna restricción en cuanto al número de opciones ni a su orden. En la siguiente tabla se indican las opciones de configuración admitidas:

Opción de agente Descripción
-cprof_service Si tu aplicación no se ejecuta en App Engine, debes usar esta opción de configuración para definir el nombre del servicio. Para ver las restricciones de los nombres de servicio, consulta Argumentos de nombre y versión de servicio.
-cprof_service_version Si quieres analizar los datos de perfil mediante la interfaz de usuario de Profiler por versión del servicio, usa esta opción para definir la versión. Para ver las restricciones de versión, consulta Argumentos de nombre y versión del servicio.
-cprof_project_id Si no estás ejecutando el comando en Google Cloud, usa esta opción para especificar el ID de tu proyecto Google Cloud . Para obtener más información, consulta Crear perfiles de aplicaciones que se ejecutan fuera de Google Cloud.
-cprof_zone_name Cuando tu aplicación se ejecuta en Google Cloud, el agente de creación de perfiles determina la zona comunicándose con el servicio de metadatos de Compute Engine. Si el agente de creación de perfiles no puede comunicarse con el servicio de metadatos, debes usar esta opción.
-cprof_gce_metadata_server_retry_count
-cprof_gce_metadata_server_retry_sleep_sec
Juntas, estas dos opciones definen la política de reintentos que usa el agente del creador de perfiles cuando se comunica con el servicio de metadatos de Compute Engine. para obtener el Google Cloud ID del proyecto y la información de la zona.

La política predeterminada es volver a intentar la operación hasta 3 veces, con un intervalo de 1 segundo entre cada intento. Esta política es suficiente para la mayoría de las configuraciones.
-cprof_cpu_use_per_thread_timers Para obtener los perfiles de tiempo de CPU más precisos, asigna el valor true a esta opción. Si se usa esta opción, aumenta la sobrecarga por subproceso.

El valor predeterminado es false.
-cprof_force_debug_non_safepoints De forma predeterminada, el agente de creación de perfiles obliga a la JVM a generar información de depuración para todo el código generado justo a tiempo (JIT), además de generar información de depuración para todos los puntos seguros. De esta forma, se obtiene la información más precisa sobre la ubicación de funciones y líneas para los perfiles de tiempo de CPU y de montículo, pero a costa de una sobrecarga adicional del agente. Puedes inhabilitar la generación de información de depuración para el código JIT si asignas el valor false a esta opción.

El valor predeterminado es true.
-cprof_wall_num_threads_cutoff De forma predeterminada, los perfiles de muro no se recogen si el número total de hilos de la aplicación supera los 4096. El límite asegura que, durante la recogida de perfiles, el coste de recorrer la pila de subprocesos sea mínimo. Si tu servicio suele tener más de 4096 subprocesos y quieres recoger datos de perfil a costa de una sobrecarga adicional, usa esta marca para aumentar el límite.

El límite predeterminado es de 4096 subprocesos.
-cprof_enable_heap_sampling Para habilitar la creación de perfiles de montículo en Java 11 y versiones posteriores, define
-cprof_enable_heap_sampling=true. La creación de perfiles de montículo no es compatible con Java 10 ni con versiones anteriores.

La creación de perfiles de montículo está inhabilitada de forma predeterminada.

Cuando habilitas la creación de perfiles de montículo, el intervalo de muestreo se define en 512 KiB de forma predeterminada. Este intervalo es suficiente para la mayoría de las aplicaciones y supone una sobrecarga inferior al 0,5% para la aplicación. Se admiten intervalos de muestreo de entre 256 KiB (262.144) y 1024 KiB (1.048.576). Por ejemplo, para definir el intervalo de muestreo en 256 KiB, lo que duplica la frecuencia de muestreo, añade la opción del agente:
-cprof_heap_sampling_interval=262144
Del mismo modo, para definir el intervalo de muestreo en 1024 KiB, lo que reduce a la mitad la frecuencia de muestreo, añade la opción del agente:
-cprof_heap_sampling_interval=1048576
Si habilitas este tipo de perfil, especifica una nueva versión de servicio cuando implementes tu aplicación. Para obtener más información, consulta ¿Por qué no tengo datos de un tipo de perfil concreto?

Argumentos de nombre y versión del servicio

Cuando carga el agente de Profiler, especifica un argumento service-name y un argumento service-version opcional para configurarlo.

El nombre del servicio permite a Profiler recoger datos de perfil de todas las réplicas de ese servicio. El servicio de creación de perfiles asegura una frecuencia de recogida de un perfil por minuto, de media, para cada nombre de servicio en cada combinación de versiones y zonas de servicio.

Por ejemplo, si tienes un servicio con dos versiones que se ejecutan en réplicas de tres zonas, el creador de perfiles creará una media de seis perfiles por minuto para ese servicio.

Si usas nombres de servicio diferentes para tus réplicas, tu servicio se perfilará con más frecuencia de la necesaria, con una sobrecarga correspondientemente mayor.

Al seleccionar un nombre de servicio, ten en cuenta lo siguiente:

  • Elige un nombre que represente claramente el servicio en la arquitectura de tu aplicación. La elección del nombre del servicio es menos importante si solo ejecutas un servicio o una aplicación. Es más importante si tu aplicación se ejecuta como un conjunto de microservicios, por ejemplo.

  • No utilices ningún valor específico del proceso, como un ID de proceso, en la cadena service-name.

  • La cadena service-name debe coincidir con esta expresión regular:

    ^[a-z0-9]([-a-z0-9_.]{0,253}[a-z0-9])?$

Una buena práctica es usar una cadena estática como imageproc-service como nombre del servicio.

La versión del servicio es opcional. Si especificas la versión del servicio, Profiler puede agregar información de perfil de varias instancias y mostrarla correctamente. Se puede usar para marcar diferentes versiones de tus servicios a medida que se implementan. La interfaz de usuario de Profiler te permite filtrar los datos por versión del servicio. De esta forma, puedes comparar el rendimiento de versiones anteriores y más recientes del código.

El valor del argumento service-version es una cadena de formato libre, pero los valores de este argumento suelen ser números de versión, como 1.0.0 o 2.1.2.

Empezar tu programa

Compute Engine

Inicia Java como lo harías normalmente para ejecutar tu programa y añade las opciones de configuración del agente:

java \
    -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-cprof_service_version=1.0.0 \
    JAVA_OPTIONS -jar PATH_TO_YOUR_JAR_FILE PROGRAM_OPTIONS

GKE

Modifica el Dockerfile del contenedor de servicio para iniciar Java como lo harías normalmente para ejecutar tu programa y añade las opciones de configuración del agente:

CMD ["java", \
    "-agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-cprof_service_version=1.0.0", \
     "-jar", "PATH_TO_YOUR_JAR_FILE" ]
    

Entorno flexible

Modifica el archivo de configuración app.yaml para definir la variable de entorno PROFILER_ENABLE. A continuación, inicia tu programa como de costumbre:

env_variables:
   PROFILER_ENABLE: true

Para obtener más información, consulta Definir variables de entorno.

Entorno estándar

Entorno de tiempo de ejecución de Java 21

Si no usas servicios antiguos agrupados, habilita la recogida de datos del generador de perfiles modificando el archivo app.yaml para especificar la marca agentpath con uno de los siguientes métodos:

  • Define la variable de entorno JAVA_TOOL_OPTIONS:

    runtime: java21
    env_variables:
      JAVA_TOOL_OPTIONS: "-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true"
    
  • Especifica el agentpath mediante el elemento entrypoint:

    runtime: java21
    entrypoint: java \
      -agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true \
      Main.java
    

Si usas servicios antiguos agrupados, habilita la recogida de datos del generador de perfiles modificando el archivo appengine-web.xml para especificar la marca agentpath con uno de los siguientes métodos:

  • Define la variable de entorno JAVA_USER_OPTS:

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <env-variables>
    <env-var name="JAVA_USER_OPTS" value="-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true" />
    </env-variables>
    </appengine-web-app>
  • Define la variable de entorno CPROF_ENABLE:

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <env-variables>
    <env-var name="CPROF_ENABLE" value="-agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true" />
    </env-variables>
    </appengine-web-app>
  • Especifica el agentpath mediante el elemento entrypoint:

    <?xml version="1.0" encoding="utf-8"?>
    <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
      <entrypoint>
       java
       -agentpath:/opt/cprof/profiler_java_agent.so=-logtostderr,-cprof_enable_heap_sampling=true
      </entrypoint>
    </appengine-web-app>

Si se configura un nuevo tipo de perfil para la recogida de datos, asegúrese de especificar una nueva versión del servicio al implementar su aplicación. Para obtener más información, consulta ¿Por qué no tengo datos de un tipo de perfil concreto?

Registro de agentes

El agente de creación de perfiles puede registrar información de los entornos flexibles de App Engine, Compute Engine y GKE. El agente de creación de perfiles admite los siguientes niveles de registro:

  • 0: registra todos los mensajes. Nivel de registro predeterminado.
  • 1: registra mensajes de advertencia, error y error grave.
  • 2: registra los errores y los mensajes de error irrecuperables.
  • 3: registra solo los mensajes de error y detiene la aplicación.

Para habilitar la escritura de registros en el error estándar con el nivel de registro predeterminado, añade -logtostderr a la configuración de -agentpath.

Para definir el nivel de registro de forma que solo se registren los mensajes de error y los errores graves, añade -minloglevel=2 a la configuración de -agentpath.

Por ejemplo, para habilitar el registro de mensajes de error y de error fatal en el error estándar, añade -logtostderr y ‑minloglevel=2 a la configuración de -agentpath:

 java -agentpath:/opt/cprof/profiler_java_agent.so=-cprof_service=myapp,-logtostderr,-minloglevel=2 \
   -jar myApp.jar

Solución de problemas

En esta sección se enumeran los problemas específicos de la creación de perfiles de aplicaciones Java. Consulta la sección Solución de problemas para obtener ayuda con problemas habituales.

Comportamiento Causa Solución
Has habilitado varios creadores de perfiles de montículo y no tienes datos de perfil. Si se usan varios generadores de perfiles de montículo simultáneamente, se inhabilitará la compatibilidad con todos los generadores de perfiles de montículo de Java. Esta es una limitación de la JVM. Habilita un profiler.

Ejecutar con Linux Alpine

El agente de creación de perfiles de Java para Linux Alpine solo se admite en configuraciones de Google Kubernetes Engine.

Para instalar el agente de creación de perfiles de Java más reciente para Linux Alpine, consulta Instalar el agente de Profiler.

Error de autenticación

Si usas imágenes de Docker que se ejecutan con Linux Alpine (como golang:alpine o alpine), es posible que veas el siguiente error de autenticación:

connection error: desc = "transport: authentication handshake failed: x509: failed to load system roots and no roots provided"

Ten en cuenta que, para ver el error, debes tener habilitado el registro del agente.

El error indica que las imágenes de Docker con Linux Alpine no tienen instalados los certificados SSL raíz de forma predeterminada. Estos certificados son necesarios para que el agente de creación de perfiles se comunique con la API Profiler. Para resolver este error, añade el siguiente comando apk a tu Dockerfile:

FROM alpine
...
RUN apk add --no-cache ca-certificates

Después, debes volver a compilar y desplegar la aplicación.

Siguientes pasos